feat/dotcom: use Enterprise Portal for Cody Gateway usage (#63653)

Closes https://linear.app/sourcegraph/issue/CORE-211

See https://linear.app/sourcegraph/issue/CORE-100 for a higher-level
view - this is the first proof-of-concept for achieving our migration
strategy to extract Enterprise subscription data out of dotcom while
retaining the existing UI until a future project ships a dedicated
Enterprise Portal UI
(https://linear.app/sourcegraph/project/kr-p-enterprise-portal-user-interface-dadd5ff28bd8).

The integration uses generated ConnectRPC client code + `react-query`,
the latter of which has already been used elsewhere for SSC
integrations. This is partly supported by
https://github.com/connectrpc/connect-query-es which offers
mostly-first-class integration with `react-query`, but I had to do some
fenangling to provide the query clients directly as I can't get the
React provider thing to work. The ConnectRPC clients point to the
proxies introduced in
https://github.com/sourcegraph/sourcegraph/pull/63652 which
authenticates the requests for Enterprise Portal, until we ship
https://linear.app/sourcegraph/project/kr-p1-streamlined-role-assignment-via-sams-and-entitle-2f118b3f9d4c/overview

## Test plan

### Local

First, `sg start dotcom`

Choose a subscription you have locally. Use `psql -d sourcegraph` to
connect to local database, then:

```
sourcegraph=# delete from product_licenses where product_subscription_id = '<local subscription ID>';
DELETE 1
sourcegraph=# update product_subscriptions set id = '58b95c21-c2d0-4b4b-8b15-bf1b926d3557' where id = '<local subscription ID>';
UPDATE 1
```

Now annoyingly the UI will break because there is no license, we need:

```gql
query getGraphQLID {
  dotcom {
    productSubscription(uuid:"58b95c21-c2d0-4b4b-8b15-bf1b926d3557") {
      id # graphQL ID
    }
  }
}

mutation createLicense {
  dotcom {
    generateProductLicenseForSubscription(productSubscriptionID:"<graphQLID>", license:{
      tags:["dev"]
      userCount:100
      expiresAt:1814815397
    }) {
      id
    }
  }
}
```

This effectively lets us have a "pretend S2" subscription locally.
Visiting the subscription page now at
https://sourcegraph.test:3443/site-admin/dotcom/product/subscriptions/58b95c21-c2d0-4b4b-8b15-bf1b926d3557


![image](https://github.com/sourcegraph/sourcegraph/assets/23356519/1e77d77d-8032-436b-ab1d-393b34e8e4b5)

The data matches the "real" data currently at
https://sourcegraph.com/site-admin/dotcom/product/subscriptions/58b95c21-c2d0-4b4b-8b15-bf1b926d3557

### Against dotcom

```
sg start web-standalone
```

follow
https://www.loom.com/share/6cb3b3ca475b4b9392aa4b11938e76e6?sid=6cd1a689-d75d-4133-bcff-b0c7d25b23f1
and then check out some product subscriptions
This commit is contained in:
Robert Lin 2024-07-10 12:22:08 -07:00 committed by GitHub
parent d47b4cc48b
commit 857d5200b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 1043 additions and 135 deletions

View File

@ -30,6 +30,8 @@ const config = {
'typedoc.js',
'client/web/dev/**/*',
'graphql-schema-linter.config.js',
// Generated code
'client/web/src/enterprise/site-admin/dotcom/productSubscriptions/enterpriseportalgen/**',
],
extends: ['@sourcegraph/eslint-config', 'plugin:storybook/recommended'],
env: {

View File

@ -70,3 +70,6 @@ dev/linearhooks/internal/lineargql/schema.graphql
# This is an embedded external minified library and should not be modified
internal/appliance/web/static/script/htmx.min.js
internal/appliance/web/static/script/bootstrap.bundle.min.js
# Generated code
client/web/src/enterprise/site-admin/dotcom/productSubscriptions/enterpriseportalgen/**

View File

@ -30,4 +30,4 @@
"@sourcegraph/wildcard": "workspace:*"
},
"sideEffects": true
}
}

View File

@ -1056,6 +1056,9 @@ ts_project(
"src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminProductSubscriptionPage.tsx",
"src/enterprise/site-admin/dotcom/productSubscriptions/SiteAdminProductSubscriptionsPage.tsx",
"src/enterprise/site-admin/dotcom/productSubscriptions/backend.ts",
"src/enterprise/site-admin/dotcom/productSubscriptions/enterpriseportal.ts",
"src/enterprise/site-admin/dotcom/productSubscriptions/enterpriseportalgen/codyaccess-CodyAccessService_connectquery.ts",
"src/enterprise/site-admin/dotcom/productSubscriptions/enterpriseportalgen/codyaccess_pb.ts",
"src/enterprise/site-admin/dotcom/productSubscriptions/plandata.ts",
"src/enterprise/site-admin/dotcom/productSubscriptions/testUtils.ts",
"src/enterprise/site-admin/dotcom/productSubscriptions/utils.ts",
@ -1754,6 +1757,7 @@ ts_project(
":node_modules/@types/node",
":node_modules/mermaid",
"//:node_modules/@apollo/client",
"//:node_modules/@bufbuild/protobuf",
"//:node_modules/@codemirror/commands",
"//:node_modules/@codemirror/lang-json",
"//:node_modules/@codemirror/lang-markdown",
@ -1762,6 +1766,9 @@ ts_project(
"//:node_modules/@codemirror/search",
"//:node_modules/@codemirror/state",
"//:node_modules/@codemirror/view",
"//:node_modules/@connectrpc/connect",
"//:node_modules/@connectrpc/connect-query",
"//:node_modules/@connectrpc/connect-web",
"//:node_modules/@date-fns/utc",
"//:node_modules/@graphiql/react",
"//:node_modules/@lezer/common", #keep

View File

@ -1,14 +1,15 @@
import React, { useCallback, useState } from 'react'
import type { ConnectError } from '@connectrpc/connect'
import { mdiPencil, mdiTrashCan } from '@mdi/js'
import { parseISO } from 'date-fns'
import type { UseQueryResult } from '@tanstack/react-query'
import type { GraphQLError } from 'graphql'
import { Toggle } from '@sourcegraph/branded/src/components/Toggle'
import { logger } from '@sourcegraph/common'
import { useMutation, useQuery } from '@sourcegraph/http-client'
import { useMutation } from '@sourcegraph/http-client'
import { CodyGatewayRateLimitSource } from '@sourcegraph/shared/src/graphql-operations'
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import {
H3,
ProductStatusBadge,
@ -35,26 +36,20 @@ import type {
Scalars,
UpdateCodyGatewayConfigResult,
UpdateCodyGatewayConfigVariables,
CodyGatewayRateLimitUsageDatapoint,
CodyGatewayRateLimitFields,
DotComProductSubscriptionCodyGatewayCompletionsUsageResult,
DotComProductSubscriptionCodyGatewayCompletionsUsageVariables,
DotComProductSubscriptionCodyGatewayEmbeddingsUsageVariables,
DotComProductSubscriptionCodyGatewayEmbeddingsUsageResult,
} from '../../../../graphql-operations'
import { ChartContainer } from '../../../../site-admin/analytics/components/ChartContainer'
import {
DOTCOM_PRODUCT_SUBSCRIPTION_CODY_GATEWAY_COMPLETIONS_USAGE,
DOTCOM_PRODUCT_SUBSCRIPTION_CODY_GATEWAY_EMBEDDINGS_USAGE,
UPDATE_CODY_GATEWAY_CONFIG,
} from './backend'
import { UPDATE_CODY_GATEWAY_CONFIG } from './backend'
import { CodyGatewayRateLimitModal } from './CodyGatewayRateLimitModal'
import { useGetCodyGatewayUsage, type EnterprisePortalEnvironment } from './enterpriseportal'
import type { CodyGatewayUsage_UsageDatapoint, GetCodyGatewayUsageResponse } from './enterpriseportalgen/codyaccess_pb'
import { numberFormatter, prettyInterval } from './utils'
import styles from './CodyServicesSection.module.scss'
interface Props extends TelemetryV2Props {
enterprisePortalEnvironment: EnterprisePortalEnvironment
productSubscriptionUUID: string
productSubscriptionID: Scalars['ID']
currentSourcegraphAccessToken: string | null
@ -65,6 +60,7 @@ interface Props extends TelemetryV2Props {
}
export const CodyServicesSection: React.FunctionComponent<Props> = ({
enterprisePortalEnvironment,
productSubscriptionUUID,
productSubscriptionID,
viewerCanAdminister,
@ -74,6 +70,9 @@ export const CodyServicesSection: React.FunctionComponent<Props> = ({
codyGatewayAccess,
telemetryRecorder,
}) => {
// TODO: Figure out strategy for what instance to target
const codyGatewayUsageQuery = useGetCodyGatewayUsage(enterprisePortalEnvironment, productSubscriptionUUID)
const [updateCodyGatewayConfig, { loading: updateCodyGatewayConfigLoading, error: updateCodyGatewayConfigError }] =
useMutation<UpdateCodyGatewayConfigResult, UpdateCodyGatewayConfigVariables>(UPDATE_CODY_GATEWAY_CONFIG)
@ -175,7 +174,7 @@ export const CodyServicesSection: React.FunctionComponent<Props> = ({
/>
</tbody>
</table>
<RateLimitUsage mode="completions" productSubscriptionUUID={productSubscriptionUUID} />
<RateLimitUsage mode="completions" usageQuery={codyGatewayUsageQuery} />
<hr className="my-3" />
@ -201,10 +200,7 @@ export const CodyServicesSection: React.FunctionComponent<Props> = ({
/>
</tbody>
</table>
<EmbeddingsRateLimitUsage
mode="embeddings"
productSubscriptionUUID={productSubscriptionUUID}
/>
<EmbeddingsRateLimitUsage mode="embeddings" usageQuery={codyGatewayUsageQuery} />
</>
)}
@ -277,8 +273,8 @@ export const CodyGatewayRateLimitSourceBadge: React.FunctionComponent<{
}
}
function generateSeries(data: CodyGatewayRateLimitUsageDatapoint[]): [string, CodyGatewayRateLimitUsageDatapoint[]][] {
const series: Record<string, CodyGatewayRateLimitUsageDatapoint[]> = {}
function generateSeries(data: CodyGatewayUsage_UsageDatapoint[]): [string, CodyGatewayUsage_UsageDatapoint[]][] {
const series: Record<string, CodyGatewayUsage_UsageDatapoint[]> = {}
for (const entry of data) {
if (!series[entry.model]) {
series[entry.model] = []
@ -411,17 +407,12 @@ const RateLimitRow: React.FunctionComponent<RateLimitRowProps> = ({
}
interface RateLimitUsageProps {
productSubscriptionUUID: string
usageQuery: UseQueryResult<GetCodyGatewayUsageResponse, ConnectError>
mode: 'completions' | 'embeddings'
}
const RateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = ({ productSubscriptionUUID }) => {
const { data, loading, error } = useQuery<
DotComProductSubscriptionCodyGatewayCompletionsUsageResult,
DotComProductSubscriptionCodyGatewayCompletionsUsageVariables
>(DOTCOM_PRODUCT_SUBSCRIPTION_CODY_GATEWAY_COMPLETIONS_USAGE, { variables: { uuid: productSubscriptionUUID } })
if (loading && !data) {
const RateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = ({ usageQuery: { data, isLoading, error } }) => {
if (isLoading && !data) {
return (
<>
<H5 className="mb-2">Usage</H5>
@ -439,8 +430,7 @@ const RateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = ({ productS
)
}
const { codyGatewayAccess } = data!.dotcom.productSubscription
const usage = data?.usage
return (
<>
<H5 className="mb-2">Usage</H5>
@ -450,28 +440,28 @@ const RateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = ({ productS
width={width}
height={200}
series={[
...generateSeries(codyGatewayAccess.chatCompletionsRateLimit?.usage ?? []).map(
([model, data]): Series<CodyGatewayRateLimitUsageDatapoint> => ({
...generateSeries(usage?.chatCompletionsUsage ?? []).map(
([model, data]): Series<CodyGatewayUsage_UsageDatapoint> => ({
data,
getXValue(datum) {
return parseISO(datum.date)
return datum.time?.toDate() || new Date()
},
getYValue(datum) {
return Number(datum.count)
return Number(datum.usage)
},
id: 'chat-usage',
name: 'Chat completions: ' + model,
color: 'var(--purple)',
})
),
...generateSeries(codyGatewayAccess.codeCompletionsRateLimit?.usage ?? []).map(
([model, data]): Series<CodyGatewayRateLimitUsageDatapoint> => ({
...generateSeries(data?.usage?.codeCompletionsUsage ?? []).map(
([model, data]): Series<CodyGatewayUsage_UsageDatapoint> => ({
data,
getXValue(datum) {
return parseISO(datum.date)
return datum.time?.toDate() || new Date()
},
getYValue(datum) {
return Number(datum.count)
return Number(datum.usage)
},
id: 'code-completions-usage',
name: 'Code completions: ' + model,
@ -486,13 +476,10 @@ const RateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = ({ productS
)
}
const EmbeddingsRateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = ({ productSubscriptionUUID }) => {
const { data, loading, error } = useQuery<
DotComProductSubscriptionCodyGatewayEmbeddingsUsageResult,
DotComProductSubscriptionCodyGatewayEmbeddingsUsageVariables
>(DOTCOM_PRODUCT_SUBSCRIPTION_CODY_GATEWAY_EMBEDDINGS_USAGE, { variables: { uuid: productSubscriptionUUID } })
if (loading && !data) {
const EmbeddingsRateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = ({
usageQuery: { data, isLoading, error },
}) => {
if (isLoading && !data) {
return (
<>
<H5 className="mb-2">Usage</H5>
@ -510,8 +497,7 @@ const EmbeddingsRateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = (
)
}
const { codyGatewayAccess } = data!.dotcom.productSubscription
const usage = data?.usage
return (
<>
<H5 className="mb-2">Usage</H5>
@ -521,16 +507,16 @@ const EmbeddingsRateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = (
width={width}
height={200}
series={[
...generateSeries(codyGatewayAccess.embeddingsRateLimit?.usage ?? []).map(
([model, data]): Series<CodyGatewayRateLimitUsageDatapoint> => ({
...generateSeries(usage?.embeddingsUsage ?? []).map(
([model, data]): Series<CodyGatewayUsage_UsageDatapoint> => ({
data,
getXValue(datum) {
return parseISO(datum.date)
return datum.time?.toDate() || new Date()
},
getYValue(datum) {
return Number(datum.count)
return Number(datum.usage)
},
id: 'chat-usage',
id: 'embeddings-usage',
name: 'Embedded tokens: ' + model,
color: 'var(--purple)',
})

View File

@ -7,7 +7,7 @@ import { catchError, concatMap, map, tap } from 'rxjs/operators'
import { asError, type ErrorLike, isErrorLike } from '@sourcegraph/common'
import { dataOrThrowErrors, gql } from '@sourcegraph/http-client'
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import { Button, useEventObservable, Link, Alert, Icon, Form, Container, PageHeader } from '@sourcegraph/wildcard'
import type { AuthenticatedUser } from '../../../../auth'

View File

@ -6,7 +6,7 @@ import { useLocation, useNavigate, useParams } from 'react-router-dom'
import { Timestamp } from '@sourcegraph/branded/src/components/Timestamp'
import { logger } from '@sourcegraph/common'
import { useMutation, useQuery } from '@sourcegraph/http-client'
import { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import type { TelemetryV2Props } from '@sourcegraph/shared/src/telemetry'
import { Button, LoadingSpinner, Link, Icon, ErrorAlert, PageHeader, Container, H3, Text } from '@sourcegraph/wildcard'
import {
@ -36,6 +36,7 @@ import {
useProductSubscriptionLicensesConnection,
} from './backend'
import { CodyServicesSection } from './CodyServicesSection'
import type { EnterprisePortalEnvironment } from './enterpriseportal'
import { SiteAdminGenerateProductLicenseForSubscriptionForm } from './SiteAdminGenerateProductLicenseForSubscriptionForm'
import { SiteAdminProductLicenseNode } from './SiteAdminProductLicenseNode'
import { accessTokenPath, errorForPath, enterprisePortalID } from './utils'
@ -122,6 +123,20 @@ export const SiteAdminProductSubscriptionPage: React.FunctionComponent<React.Pro
const productSubscription = data!.dotcom.productSubscription
/**
* TODO(@robert): As part of https://linear.app/sourcegraph/issue/CORE-100,
* eventually dev subscriptions will only live on Enterprise Portal dev and
* prod subscriptions will only live on Enterprise Portal prod. Until we
* cut over, we use license tags to determine what Enterprise Portal
* environment to target.
*/
const enterprisePortalEnvironment: EnterprisePortalEnvironment =
window.context.deployType === 'dev'
? 'local'
: productSubscription.activeLicense?.info?.tags?.includes('dev')
? 'dev'
: 'prod'
return (
<>
<div className="site-admin-product-subscription-page">
@ -198,6 +213,7 @@ export const SiteAdminProductSubscriptionPage: React.FunctionComponent<React.Pro
</Container>
<CodyServicesSection
enterprisePortalEnvironment={enterprisePortalEnvironment}
viewerCanAdminister={true}
currentSourcegraphAccessToken={productSubscription.currentSourcegraphAccessToken}
accessTokenError={errorForPath(error, accessTokenPath)}

View File

@ -67,73 +67,6 @@ export const CODY_GATEWAY_ACCESS_FIELDS_FRAGMENT = gql`
}
`
const CODY_GATEWAY_RATE_LIMIT_USAGE_FIELDS = gql`
fragment CodyGatewayRateLimitUsageFields on CodyGatewayRateLimit {
usage {
...CodyGatewayRateLimitUsageDatapoint
}
}
fragment CodyGatewayRateLimitUsageDatapoint on CodyGatewayUsageDatapoint {
date
count
model
}
`
export const CODY_GATEWAY_ACCESS_COMPLETIONS_USAGE_FIELDS_FRAGMENT = gql`
fragment CodyGatewayAccessCompletionsUsageFields on CodyGatewayAccess {
codeCompletionsRateLimit {
...CodyGatewayRateLimitUsageFields
}
chatCompletionsRateLimit {
...CodyGatewayRateLimitUsageFields
}
}
${CODY_GATEWAY_RATE_LIMIT_USAGE_FIELDS}
`
export const DOTCOM_PRODUCT_SUBSCRIPTION_CODY_GATEWAY_COMPLETIONS_USAGE = gql`
query DotComProductSubscriptionCodyGatewayCompletionsUsage($uuid: String!) {
dotcom {
productSubscription(uuid: $uuid) {
id
codyGatewayAccess {
...CodyGatewayAccessCompletionsUsageFields
}
}
}
}
${CODY_GATEWAY_ACCESS_COMPLETIONS_USAGE_FIELDS_FRAGMENT}
`
export const CODY_GATEWAY_ACCESS_EMBEDDINGS_USAGE_FIELDS_FRAGMENT = gql`
fragment CodyGatewayAccessEmbeddingsUsageFields on CodyGatewayAccess {
embeddingsRateLimit {
...CodyGatewayRateLimitUsageFields
}
}
${CODY_GATEWAY_RATE_LIMIT_USAGE_FIELDS}
`
export const DOTCOM_PRODUCT_SUBSCRIPTION_CODY_GATEWAY_EMBEDDINGS_USAGE = gql`
query DotComProductSubscriptionCodyGatewayEmbeddingsUsage($uuid: String!) {
dotcom {
productSubscription(uuid: $uuid) {
id
codyGatewayAccess {
...CodyGatewayAccessEmbeddingsUsageFields
}
}
}
}
${CODY_GATEWAY_ACCESS_EMBEDDINGS_USAGE_FIELDS_FRAGMENT}
`
export const DOTCOM_PRODUCT_SUBSCRIPTION = gql`
query DotComProductSubscription($uuid: String!) {
dotcom {

View File

@ -0,0 +1,98 @@
import type { ConnectError, Transport } from '@connectrpc/connect'
import { createQueryOptions, defaultOptions } from '@connectrpc/connect-query'
import { createConnectTransport } from '@connectrpc/connect-web'
import { QueryClient, type UseQueryResult, useQuery } from '@tanstack/react-query'
import { getCodyGatewayUsage } from './enterpriseportalgen/codyaccess-CodyAccessService_connectquery'
import type { GetCodyGatewayUsageResponse } from './enterpriseportalgen/codyaccess_pb'
/**
* Use a shared QueryClient defined here and explicitly provided to react-query
* for now to avoid bleading the QueryClientProvider to the site admin parent.
*
* Another problem is that @robert was unable to get QueryClientProvider working
* even when placing it at various points the the tree.
*
* Overall this is only meant to be an interim integration, until Enterprise
* Portal gets its own dedicated UI:
* https://linear.app/sourcegraph/project/kr-p-enterprise-portal-user-interface-dadd5ff28bd8
*/
const queryClient = new QueryClient({ defaultOptions })
/**
* Use proxy that routes to a locally running Enterprise Portal at localhost:6081
*
* See cmd/frontend/internal/enterpriseportal/enterpriseportal_proxy.go
*/
const enterprisePortalLocal = createConnectTransport({
baseUrl: '/.api/enterpriseportal/local',
})
/**
* Use proxy that routes to the production Enterprise Portal at enterprise-portal.sourcegraph.com
*
* See cmd/frontend/internal/enterpriseportal/enterpriseportal_proxy.go
*/
const enterprisePortalDev = createConnectTransport({
baseUrl: '/.api/enterpriseportal/dev',
})
/**
* Use proxy that routes to the dev Enterprise Portal at enterprise-portal.sgdev.org
*
* See cmd/frontend/internal/enterpriseportal/enterpriseportal_proxy.go
*/
const enterprisePortalProd = createConnectTransport({
baseUrl: '/.api/enterpriseportal/prod',
})
/**
* Environment describes the Enteprise Portal instance to target. This can vary
* per-subscription, as we currently use an unified management UI in Sourcegraph.com
* as opposed to an Enterprise-Portal-specific UI, until:
* https://linear.app/sourcegraph/project/kr-p-enterprise-portal-user-interface-dadd5ff28bd8
*
* 'local' is only valid in local dev.
*/
export type EnterprisePortalEnvironment =
| 'prod' // enterprisePortalProd
| 'dev' // enterprisePortalDev
| 'local' // enterprisePortalLocal
const environments = new Map<EnterprisePortalEnvironment, Transport>([
['prod', enterprisePortalProd],
['dev', enterprisePortalDev],
['local', enterprisePortalLocal],
])
function mustGetEnvironment(env: EnterprisePortalEnvironment): Transport {
if (env === 'local' && window.context.deployType !== 'dev') {
throw new Error(`Environment ${env} not allowed outside local dev`)
}
const transport = environments.get(env)
if (transport) {
return transport
}
throw new Error(`Environment ${env} not configured`)
}
/**
* Retrieves Cody Gateway usage for a given subscription.
* @param env Enterprise Portal environment to target.
* @param subscriptionUUID Enterprise Subscription UUID.
*/
export function useGetCodyGatewayUsage(
env: EnterprisePortalEnvironment,
subscriptionUUID: string
): UseQueryResult<GetCodyGatewayUsageResponse, ConnectError> {
return useQuery(
createQueryOptions(
getCodyGatewayUsage,
{
query: { value: subscriptionUUID, case: 'subscriptionId' },
},
{ transport: mustGetEnvironment(env) }
),
queryClient
)
}

View File

@ -0,0 +1,77 @@
// @generated by protoc-gen-connect-query v1.4.1 with parameter "target=ts"
// @generated from file codyaccess.proto (package enterpriseportal.codyaccess.v1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { MethodIdempotency, MethodKind } from "@bufbuild/protobuf";
import { GetCodyGatewayAccessRequest, GetCodyGatewayAccessResponse, GetCodyGatewayUsageRequest, GetCodyGatewayUsageResponse, ListCodyGatewayAccessesRequest, ListCodyGatewayAccessesResponse, UpdateCodyGatewayAccessRequest, UpdateCodyGatewayAccessResponse } from "./codyaccess_pb.js";
/**
* Retrieve Cody Gateway access granted to an Enterprise subscription.
*
* @generated from rpc enterpriseportal.codyaccess.v1.CodyAccessService.GetCodyGatewayAccess
*/
export const getCodyGatewayAccess = {
localName: "getCodyGatewayAccess",
name: "GetCodyGatewayAccess",
kind: MethodKind.Unary,
I: GetCodyGatewayAccessRequest,
O: GetCodyGatewayAccessResponse,
idempotency: MethodIdempotency.NoSideEffects,
service: {
typeName: "enterpriseportal.codyaccess.v1.CodyAccessService"
}
} as const;
/**
* List all Cody Gateway accesses granted to any Enterprise subscription.
*
* @generated from rpc enterpriseportal.codyaccess.v1.CodyAccessService.ListCodyGatewayAccesses
*/
export const listCodyGatewayAccesses = {
localName: "listCodyGatewayAccesses",
name: "ListCodyGatewayAccesses",
kind: MethodKind.Unary,
I: ListCodyGatewayAccessesRequest,
O: ListCodyGatewayAccessesResponse,
idempotency: MethodIdempotency.NoSideEffects,
service: {
typeName: "enterpriseportal.codyaccess.v1.CodyAccessService"
}
} as const;
/**
* UpdateEnterpriseSubscription updates the Cody Gateway access granted to an
* Enterprise subscription.
*
* @generated from rpc enterpriseportal.codyaccess.v1.CodyAccessService.UpdateCodyGatewayAccess
*/
export const updateCodyGatewayAccess = {
localName: "updateCodyGatewayAccess",
name: "UpdateCodyGatewayAccess",
kind: MethodKind.Unary,
I: UpdateCodyGatewayAccessRequest,
O: UpdateCodyGatewayAccessResponse,
idempotency: MethodIdempotency.Idempotent,
service: {
typeName: "enterpriseportal.codyaccess.v1.CodyAccessService"
}
} as const;
/**
* GetCodyGatewayUsage returns data about a subscription's recent usage of
* Cody Gateway.
*
* @generated from rpc enterpriseportal.codyaccess.v1.CodyAccessService.GetCodyGatewayUsage
*/
export const getCodyGatewayUsage = {
localName: "getCodyGatewayUsage",
name: "GetCodyGatewayUsage",
kind: MethodKind.Unary,
I: GetCodyGatewayUsageRequest,
O: GetCodyGatewayUsageResponse,
idempotency: MethodIdempotency.NoSideEffects,
service: {
typeName: "enterpriseportal.codyaccess.v1.CodyAccessService"
}
} as const;

View File

@ -0,0 +1,719 @@
// @generated by protoc-gen-es v1.10.0 with parameter "target=ts"
// @generated from file codyaccess.proto (package enterpriseportal.codyaccess.v1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Duration, FieldMask, Message, proto3, protoInt64, Timestamp } from "@bufbuild/protobuf";
/**
* @generated from enum enterpriseportal.codyaccess.v1.CodyGatewayRateLimitSource
*/
export enum CodyGatewayRateLimitSource {
/**
* @generated from enum value: CODY_GATEWAY_RATE_LIMIT_SOURCE_UNSPECIFIED = 0;
*/
UNSPECIFIED = 0,
/**
* Indicates that a custom override for the rate limit has been configured
* and applied.
*
* @generated from enum value: CODY_GATEWAY_RATE_LIMIT_SOURCE_OVERRIDE = 1;
*/
OVERRIDE = 1,
/**
* Indicates that the rate limit is inferred by the subscription's active plan.
*
* @generated from enum value: CODY_GATEWAY_RATE_LIMIT_SOURCE_PLAN = 2;
*/
PLAN = 2,
}
// Retrieve enum metadata with: proto3.getEnumType(CodyGatewayRateLimitSource)
proto3.util.setEnumType(CodyGatewayRateLimitSource, "enterpriseportal.codyaccess.v1.CodyGatewayRateLimitSource", [
{ no: 0, name: "CODY_GATEWAY_RATE_LIMIT_SOURCE_UNSPECIFIED" },
{ no: 1, name: "CODY_GATEWAY_RATE_LIMIT_SOURCE_OVERRIDE" },
{ no: 2, name: "CODY_GATEWAY_RATE_LIMIT_SOURCE_PLAN" },
]);
/**
* @generated from message enterpriseportal.codyaccess.v1.GetCodyGatewayAccessRequest
*/
export class GetCodyGatewayAccessRequest extends Message<GetCodyGatewayAccessRequest> {
/**
* @generated from oneof enterpriseportal.codyaccess.v1.GetCodyGatewayAccessRequest.query
*/
query: {
/**
* The external, prefixed UUID-format identifier of an Enterprise subscription.
*
* @generated from field: string subscription_id = 1;
*/
value: string;
case: "subscriptionId";
} | {
/**
* An license-based access token that is valid for an Enterprise subscription's
* Cody Gateway access, e.g. 'slk_...'
*
* @generated from field: string access_token = 2;
*/
value: string;
case: "accessToken";
} | { case: undefined; value?: undefined } = { case: undefined };
constructor(data?: PartialMessage<GetCodyGatewayAccessRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.GetCodyGatewayAccessRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "subscription_id", kind: "scalar", T: 9 /* ScalarType.STRING */, oneof: "query" },
{ no: 2, name: "access_token", kind: "scalar", T: 9 /* ScalarType.STRING */, oneof: "query" },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetCodyGatewayAccessRequest {
return new GetCodyGatewayAccessRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetCodyGatewayAccessRequest {
return new GetCodyGatewayAccessRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetCodyGatewayAccessRequest {
return new GetCodyGatewayAccessRequest().fromJsonString(jsonString, options);
}
static equals(a: GetCodyGatewayAccessRequest | PlainMessage<GetCodyGatewayAccessRequest> | undefined, b: GetCodyGatewayAccessRequest | PlainMessage<GetCodyGatewayAccessRequest> | undefined): boolean {
return proto3.util.equals(GetCodyGatewayAccessRequest, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.GetCodyGatewayAccessResponse
*/
export class GetCodyGatewayAccessResponse extends Message<GetCodyGatewayAccessResponse> {
/**
* @generated from field: enterpriseportal.codyaccess.v1.CodyGatewayAccess access = 1;
*/
access?: CodyGatewayAccess;
constructor(data?: PartialMessage<GetCodyGatewayAccessResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.GetCodyGatewayAccessResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "access", kind: "message", T: CodyGatewayAccess },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetCodyGatewayAccessResponse {
return new GetCodyGatewayAccessResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetCodyGatewayAccessResponse {
return new GetCodyGatewayAccessResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetCodyGatewayAccessResponse {
return new GetCodyGatewayAccessResponse().fromJsonString(jsonString, options);
}
static equals(a: GetCodyGatewayAccessResponse | PlainMessage<GetCodyGatewayAccessResponse> | undefined, b: GetCodyGatewayAccessResponse | PlainMessage<GetCodyGatewayAccessResponse> | undefined): boolean {
return proto3.util.equals(GetCodyGatewayAccessResponse, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.CodyGatewayRateLimit
*/
export class CodyGatewayRateLimit extends Message<CodyGatewayRateLimit> {
/**
* The source of the rate limit configuration.
*
* @generated from field: enterpriseportal.codyaccess.v1.CodyGatewayRateLimitSource source = 1;
*/
source = CodyGatewayRateLimitSource.UNSPECIFIED;
/**
* Requests per time interval.
*
* @generated from field: uint64 limit = 2;
*/
limit = protoInt64.zero;
/**
* Interval for rate limiting.
*
* @generated from field: google.protobuf.Duration interval_duration = 3;
*/
intervalDuration?: Duration;
constructor(data?: PartialMessage<CodyGatewayRateLimit>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.CodyGatewayRateLimit";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "source", kind: "enum", T: proto3.getEnumType(CodyGatewayRateLimitSource) },
{ no: 2, name: "limit", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
{ no: 3, name: "interval_duration", kind: "message", T: Duration },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CodyGatewayRateLimit {
return new CodyGatewayRateLimit().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CodyGatewayRateLimit {
return new CodyGatewayRateLimit().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CodyGatewayRateLimit {
return new CodyGatewayRateLimit().fromJsonString(jsonString, options);
}
static equals(a: CodyGatewayRateLimit | PlainMessage<CodyGatewayRateLimit> | undefined, b: CodyGatewayRateLimit | PlainMessage<CodyGatewayRateLimit> | undefined): boolean {
return proto3.util.equals(CodyGatewayRateLimit, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.CodyGatewayAccessToken
*/
export class CodyGatewayAccessToken extends Message<CodyGatewayAccessToken> {
/**
* Access token for authenticating as the subscription holder with managed
* Sourcegraph services.
*
* @generated from field: string token = 1;
*/
token = "";
constructor(data?: PartialMessage<CodyGatewayAccessToken>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.CodyGatewayAccessToken";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CodyGatewayAccessToken {
return new CodyGatewayAccessToken().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CodyGatewayAccessToken {
return new CodyGatewayAccessToken().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CodyGatewayAccessToken {
return new CodyGatewayAccessToken().fromJsonString(jsonString, options);
}
static equals(a: CodyGatewayAccessToken | PlainMessage<CodyGatewayAccessToken> | undefined, b: CodyGatewayAccessToken | PlainMessage<CodyGatewayAccessToken> | undefined): boolean {
return proto3.util.equals(CodyGatewayAccessToken, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.CodyGatewayAccess
*/
export class CodyGatewayAccess extends Message<CodyGatewayAccess> {
/**
* The external, prefixed UUID-format identifier for the Enterprise
* subscription corresponding to this Cody Gateway access description
* (e.g. "es_...").
*
* @generated from field: string subscription_id = 1;
*/
subscriptionId = "";
/**
* Whether or not a subscription has Cody Gateway access enabled.
*
* @generated from field: bool enabled = 2;
*/
enabled = false;
/**
* Rate limit for chat completions access, or null if not enabled.
*
* @generated from field: optional enterpriseportal.codyaccess.v1.CodyGatewayRateLimit chat_completions_rate_limit = 3;
*/
chatCompletionsRateLimit?: CodyGatewayRateLimit;
/**
* Rate limit for code completions access, or null if not enabled.
*
* @generated from field: optional enterpriseportal.codyaccess.v1.CodyGatewayRateLimit code_completions_rate_limit = 4;
*/
codeCompletionsRateLimit?: CodyGatewayRateLimit;
/**
* Rate limit for embedding text chunks, or null if not enabled.
*
* @generated from field: optional enterpriseportal.codyaccess.v1.CodyGatewayRateLimit embeddings_rate_limit = 5;
*/
embeddingsRateLimit?: CodyGatewayRateLimit;
/**
* Available access tokens for authenticating as the subscription holder with
* Cody Gateway.
*
* @generated from field: repeated enterpriseportal.codyaccess.v1.CodyGatewayAccessToken access_tokens = 6;
*/
accessTokens: CodyGatewayAccessToken[] = [];
/**
* The display name of the corresponding Enterprise subscription.
*
* @generated from field: string subscription_display_name = 7;
*/
subscriptionDisplayName = "";
constructor(data?: PartialMessage<CodyGatewayAccess>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.CodyGatewayAccess";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "subscription_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "enabled", kind: "scalar", T: 8 /* ScalarType.BOOL */ },
{ no: 3, name: "chat_completions_rate_limit", kind: "message", T: CodyGatewayRateLimit, opt: true },
{ no: 4, name: "code_completions_rate_limit", kind: "message", T: CodyGatewayRateLimit, opt: true },
{ no: 5, name: "embeddings_rate_limit", kind: "message", T: CodyGatewayRateLimit, opt: true },
{ no: 6, name: "access_tokens", kind: "message", T: CodyGatewayAccessToken, repeated: true },
{ no: 7, name: "subscription_display_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CodyGatewayAccess {
return new CodyGatewayAccess().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CodyGatewayAccess {
return new CodyGatewayAccess().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CodyGatewayAccess {
return new CodyGatewayAccess().fromJsonString(jsonString, options);
}
static equals(a: CodyGatewayAccess | PlainMessage<CodyGatewayAccess> | undefined, b: CodyGatewayAccess | PlainMessage<CodyGatewayAccess> | undefined): boolean {
return proto3.util.equals(CodyGatewayAccess, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.ListCodyGatewayAccessesRequest
*/
export class ListCodyGatewayAccessesRequest extends Message<ListCodyGatewayAccessesRequest> {
/**
* Clients use this field to specify the maximum number of results to be
* returned by the server. The server may further constrain the maximum number
* of results returned in a single page. If the page_size is 0, the server
* will decide the number of results to be returned.
*
* See pagination concepts from https://cloud.google.com/apis/design/design_patterns#list_pagination
*
* @generated from field: int32 page_size = 1;
*/
pageSize = 0;
/**
* The client uses this field to request a specific page of the list results.
*
* See pagination concepts from https://cloud.google.com/apis/design/design_patterns#list_pagination
*
* @generated from field: string page_token = 2;
*/
pageToken = "";
constructor(data?: PartialMessage<ListCodyGatewayAccessesRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.ListCodyGatewayAccessesRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "page_size", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
{ no: 2, name: "page_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListCodyGatewayAccessesRequest {
return new ListCodyGatewayAccessesRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListCodyGatewayAccessesRequest {
return new ListCodyGatewayAccessesRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListCodyGatewayAccessesRequest {
return new ListCodyGatewayAccessesRequest().fromJsonString(jsonString, options);
}
static equals(a: ListCodyGatewayAccessesRequest | PlainMessage<ListCodyGatewayAccessesRequest> | undefined, b: ListCodyGatewayAccessesRequest | PlainMessage<ListCodyGatewayAccessesRequest> | undefined): boolean {
return proto3.util.equals(ListCodyGatewayAccessesRequest, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.ListCodyGatewayAccessesResponse
*/
export class ListCodyGatewayAccessesResponse extends Message<ListCodyGatewayAccessesResponse> {
/**
* This field represents the pagination token to retrieve the next page of
* results. If the value is "", it means no further results for the request.
*
* @generated from field: string next_page_token = 1;
*/
nextPageToken = "";
/**
* The list of Cody Gateway access that matched the given query.
*
* @generated from field: repeated enterpriseportal.codyaccess.v1.CodyGatewayAccess accesses = 2;
*/
accesses: CodyGatewayAccess[] = [];
constructor(data?: PartialMessage<ListCodyGatewayAccessesResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.ListCodyGatewayAccessesResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "next_page_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "accesses", kind: "message", T: CodyGatewayAccess, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListCodyGatewayAccessesResponse {
return new ListCodyGatewayAccessesResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListCodyGatewayAccessesResponse {
return new ListCodyGatewayAccessesResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListCodyGatewayAccessesResponse {
return new ListCodyGatewayAccessesResponse().fromJsonString(jsonString, options);
}
static equals(a: ListCodyGatewayAccessesResponse | PlainMessage<ListCodyGatewayAccessesResponse> | undefined, b: ListCodyGatewayAccessesResponse | PlainMessage<ListCodyGatewayAccessesResponse> | undefined): boolean {
return proto3.util.equals(ListCodyGatewayAccessesResponse, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.UpdateCodyGatewayAccessRequest
*/
export class UpdateCodyGatewayAccessRequest extends Message<UpdateCodyGatewayAccessRequest> {
/**
* The Cody Gateway access to update. See `update_mask` for the fields that
* can be updated.
*
* The following fields are used to identify the Cody Gateway access to update:
* - subscription_id
* Multiple fields are treated as AND-concatenated.
*
* @generated from field: enterpriseportal.codyaccess.v1.CodyGatewayAccess access = 1;
*/
access?: CodyGatewayAccess;
/**
* The list of fields to update, fields are specified relative to the CodyGatewayAccess.
* Updatable fields are:
* - enabled
* - chat_completions_rate_limit.limit
* - chat_completions_rate_limit.interval_duration
* - code_completions_rate_limit.limit
* - code_completions_rate_limit.interval_duration
* - embeddings_rate_limit.limit
* - embeddings_rate_limit.interval_duration
* An omitted `update_mask` implies that all populated fields are updated.
*
* @generated from field: google.protobuf.FieldMask update_mask = 2;
*/
updateMask?: FieldMask;
constructor(data?: PartialMessage<UpdateCodyGatewayAccessRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.UpdateCodyGatewayAccessRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "access", kind: "message", T: CodyGatewayAccess },
{ no: 2, name: "update_mask", kind: "message", T: FieldMask },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UpdateCodyGatewayAccessRequest {
return new UpdateCodyGatewayAccessRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): UpdateCodyGatewayAccessRequest {
return new UpdateCodyGatewayAccessRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): UpdateCodyGatewayAccessRequest {
return new UpdateCodyGatewayAccessRequest().fromJsonString(jsonString, options);
}
static equals(a: UpdateCodyGatewayAccessRequest | PlainMessage<UpdateCodyGatewayAccessRequest> | undefined, b: UpdateCodyGatewayAccessRequest | PlainMessage<UpdateCodyGatewayAccessRequest> | undefined): boolean {
return proto3.util.equals(UpdateCodyGatewayAccessRequest, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.UpdateCodyGatewayAccessResponse
*/
export class UpdateCodyGatewayAccessResponse extends Message<UpdateCodyGatewayAccessResponse> {
/**
* The updated Cody Gateway access.
*
* @generated from field: enterpriseportal.codyaccess.v1.CodyGatewayAccess access = 1;
*/
access?: CodyGatewayAccess;
constructor(data?: PartialMessage<UpdateCodyGatewayAccessResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.UpdateCodyGatewayAccessResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "access", kind: "message", T: CodyGatewayAccess },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UpdateCodyGatewayAccessResponse {
return new UpdateCodyGatewayAccessResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): UpdateCodyGatewayAccessResponse {
return new UpdateCodyGatewayAccessResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): UpdateCodyGatewayAccessResponse {
return new UpdateCodyGatewayAccessResponse().fromJsonString(jsonString, options);
}
static equals(a: UpdateCodyGatewayAccessResponse | PlainMessage<UpdateCodyGatewayAccessResponse> | undefined, b: UpdateCodyGatewayAccessResponse | PlainMessage<UpdateCodyGatewayAccessResponse> | undefined): boolean {
return proto3.util.equals(UpdateCodyGatewayAccessResponse, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.GetCodyGatewayUsageRequest
*/
export class GetCodyGatewayUsageRequest extends Message<GetCodyGatewayUsageRequest> {
/**
* @generated from oneof enterpriseportal.codyaccess.v1.GetCodyGatewayUsageRequest.query
*/
query: {
/**
* The external, prefixed UUID-format identifier of an Enterprise subscription.
*
* @generated from field: string subscription_id = 1;
*/
value: string;
case: "subscriptionId";
} | { case: undefined; value?: undefined } = { case: undefined };
constructor(data?: PartialMessage<GetCodyGatewayUsageRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.GetCodyGatewayUsageRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "subscription_id", kind: "scalar", T: 9 /* ScalarType.STRING */, oneof: "query" },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetCodyGatewayUsageRequest {
return new GetCodyGatewayUsageRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetCodyGatewayUsageRequest {
return new GetCodyGatewayUsageRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetCodyGatewayUsageRequest {
return new GetCodyGatewayUsageRequest().fromJsonString(jsonString, options);
}
static equals(a: GetCodyGatewayUsageRequest | PlainMessage<GetCodyGatewayUsageRequest> | undefined, b: GetCodyGatewayUsageRequest | PlainMessage<GetCodyGatewayUsageRequest> | undefined): boolean {
return proto3.util.equals(GetCodyGatewayUsageRequest, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.CodyGatewayUsage
*/
export class CodyGatewayUsage extends Message<CodyGatewayUsage> {
/**
* The external, prefixed UUID-format identifier for the Enterprise
* subscription corresponding to this Cody Gateway usage (e.g. "es_...").
*
* @generated from field: string subscription_id = 1;
*/
subscriptionId = "";
/**
* Usage data for chat completions access, or null if not enabled.
*
* @generated from field: repeated enterpriseportal.codyaccess.v1.CodyGatewayUsage.UsageDatapoint chat_completions_usage = 2;
*/
chatCompletionsUsage: CodyGatewayUsage_UsageDatapoint[] = [];
/**
* Usage data for code completions access, or null if not enabled.
*
* @generated from field: repeated enterpriseportal.codyaccess.v1.CodyGatewayUsage.UsageDatapoint code_completions_usage = 3;
*/
codeCompletionsUsage: CodyGatewayUsage_UsageDatapoint[] = [];
/**
* Usage data for embedding text chunks, or null if not enabled.
*
* @generated from field: repeated enterpriseportal.codyaccess.v1.CodyGatewayUsage.UsageDatapoint embeddings_usage = 4;
*/
embeddingsUsage: CodyGatewayUsage_UsageDatapoint[] = [];
constructor(data?: PartialMessage<CodyGatewayUsage>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.CodyGatewayUsage";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "subscription_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "chat_completions_usage", kind: "message", T: CodyGatewayUsage_UsageDatapoint, repeated: true },
{ no: 3, name: "code_completions_usage", kind: "message", T: CodyGatewayUsage_UsageDatapoint, repeated: true },
{ no: 4, name: "embeddings_usage", kind: "message", T: CodyGatewayUsage_UsageDatapoint, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CodyGatewayUsage {
return new CodyGatewayUsage().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CodyGatewayUsage {
return new CodyGatewayUsage().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CodyGatewayUsage {
return new CodyGatewayUsage().fromJsonString(jsonString, options);
}
static equals(a: CodyGatewayUsage | PlainMessage<CodyGatewayUsage> | undefined, b: CodyGatewayUsage | PlainMessage<CodyGatewayUsage> | undefined): boolean {
return proto3.util.equals(CodyGatewayUsage, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.CodyGatewayUsage.UsageDatapoint
*/
export class CodyGatewayUsage_UsageDatapoint extends Message<CodyGatewayUsage_UsageDatapoint> {
/**
* The time the usage occurred. Currently the time is always the day.
*
* @generated from field: google.protobuf.Timestamp time = 1;
*/
time?: Timestamp;
/**
* The usage for the corresponding time period.
*
* @generated from field: uint64 usage = 2;
*/
usage = protoInt64.zero;
/**
* The model that was used.
*
* @generated from field: string model = 3;
*/
model = "";
constructor(data?: PartialMessage<CodyGatewayUsage_UsageDatapoint>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.CodyGatewayUsage.UsageDatapoint";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "time", kind: "message", T: Timestamp },
{ no: 2, name: "usage", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
{ no: 3, name: "model", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CodyGatewayUsage_UsageDatapoint {
return new CodyGatewayUsage_UsageDatapoint().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CodyGatewayUsage_UsageDatapoint {
return new CodyGatewayUsage_UsageDatapoint().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CodyGatewayUsage_UsageDatapoint {
return new CodyGatewayUsage_UsageDatapoint().fromJsonString(jsonString, options);
}
static equals(a: CodyGatewayUsage_UsageDatapoint | PlainMessage<CodyGatewayUsage_UsageDatapoint> | undefined, b: CodyGatewayUsage_UsageDatapoint | PlainMessage<CodyGatewayUsage_UsageDatapoint> | undefined): boolean {
return proto3.util.equals(CodyGatewayUsage_UsageDatapoint, a, b);
}
}
/**
* @generated from message enterpriseportal.codyaccess.v1.GetCodyGatewayUsageResponse
*/
export class GetCodyGatewayUsageResponse extends Message<GetCodyGatewayUsageResponse> {
/**
* @generated from field: enterpriseportal.codyaccess.v1.CodyGatewayUsage usage = 1;
*/
usage?: CodyGatewayUsage;
constructor(data?: PartialMessage<GetCodyGatewayUsageResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "enterpriseportal.codyaccess.v1.GetCodyGatewayUsageResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "usage", kind: "message", T: CodyGatewayUsage },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetCodyGatewayUsageResponse {
return new GetCodyGatewayUsageResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetCodyGatewayUsageResponse {
return new GetCodyGatewayUsageResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetCodyGatewayUsageResponse {
return new GetCodyGatewayUsageResponse().fromJsonString(jsonString, options);
}
static equals(a: GetCodyGatewayUsageResponse | PlainMessage<GetCodyGatewayUsageResponse> | undefined, b: GetCodyGatewayUsageResponse | PlainMessage<GetCodyGatewayUsageResponse> | undefined): boolean {
return proto3.util.equals(GetCodyGatewayUsageResponse, a, b);
}
}

View File

@ -15,3 +15,11 @@ plugins:
out: .
opt:
- paths=source_relative
# Generate connectrpc bindings in Typescript: https://buf.build/connectrpc/query-es?version=v1.4.1
- plugin: buf.build/connectrpc/query-es:v1.4.1
out: ../../../../client/web/src/enterprise/site-admin/dotcom/productSubscriptions/enterpriseportalgen
opt: target=ts
- plugin: buf.build/bufbuild/es:v1.10.0
out: ../../../../client/web/src/enterprise/site-admin/dotcom/productSubscriptions/enterpriseportalgen
opt: target=ts

View File

@ -427,7 +427,11 @@
"webextension-polyfill": "^0.6.0",
"whatwg-url": "^14.0.0",
"yaml-ast-parser": "^0.0.43",
"zustand": "^3.6.9"
"zustand": "^3.6.9",
"@bufbuild/protobuf": "^1.10.0",
"@connectrpc/connect": "^1.4.0",
"@connectrpc/connect-query": "^1.4.1",
"@connectrpc/connect-web": "^1.4.0"
},
"packageManager": "pnpm@8.9.2",
"pnpm": {
@ -478,4 +482,4 @@
"cssnano": "4.1.10",
"tslib": "2.1.0"
}
}
}

View File

@ -19,6 +19,9 @@ importers:
'@apollo/client':
specifier: ^3.8.0-alpha.7
version: 3.8.0-alpha.7(graphql-ws@5.15.0)(graphql@15.4.0)(react-dom@18.1.0)(react@18.1.0)
'@bufbuild/protobuf':
specifier: ^1.10.0
version: 1.10.0
'@codemirror/autocomplete':
specifier: ^6.1.0
version: 6.1.0(@codemirror/language@6.2.0)(@codemirror/state@6.4.0)(@codemirror/view@6.26.3)(@lezer/common@1.0.0)
@ -49,6 +52,15 @@ importers:
'@codemirror/view':
specifier: ^6.26.3
version: 6.26.3
'@connectrpc/connect':
specifier: ^1.4.0
version: 1.4.0(@bufbuild/protobuf@1.10.0)
'@connectrpc/connect-query':
specifier: ^1.4.1
version: 1.4.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0)(@tanstack/react-query@5.39.0)(react-dom@18.1.0)(react@18.1.0)
'@connectrpc/connect-web':
specifier: ^1.4.0
version: 1.4.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0)
'@date-fns/utc':
specifier: ^1.1.1
version: 1.1.1
@ -3650,6 +3662,10 @@ packages:
resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==}
dev: false
/@bufbuild/protobuf@1.10.0:
resolution: {integrity: sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==}
dev: false
/@codemirror/autocomplete@6.1.0(@codemirror/language@6.2.0)(@codemirror/state@6.4.0)(@codemirror/view@6.26.3)(@lezer/common@1.0.0):
resolution: {integrity: sha512-wtO4O5WDyXhhCd4q4utDIDZxnQfmJ++3dGBCG9LMtI79+92OcA1DVk/n7BEupKmjIr8AzvptDz7YQ9ud6OkU+A==}
peerDependencies:
@ -3780,6 +3796,41 @@ packages:
requiresBuild: true
dev: true
/@connectrpc/connect-query@1.4.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0)(@tanstack/react-query@5.39.0)(react-dom@18.1.0)(react@18.1.0):
resolution: {integrity: sha512-kRv0ka+kSBpnG/56H/vLbQEHkcaFkVb2tZ4fo5m6V3AxKMFvrl35i2nO7+9cmPjhzzbTbE8W/zJqYZkO4YE+FA==}
peerDependencies:
'@bufbuild/protobuf': ^1.3.3
'@connectrpc/connect': ^1.1.2
'@tanstack/react-query': 5.x
react: ^18.3.1
react-dom: ^18.3.1
dependencies:
'@bufbuild/protobuf': 1.10.0
'@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0)
'@tanstack/react-query': 5.39.0(react@18.1.0)
react: 18.1.0
react-dom: 18.1.0(react@18.1.0)
stable-hash: 0.0.4
dev: false
/@connectrpc/connect-web@1.4.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0):
resolution: {integrity: sha512-13aO4psFbbm7rdOFGV0De2Za64DY/acMspgloDlcOKzLPPs0yZkhp1OOzAQeiAIr7BM/VOHIA3p8mF0inxCYTA==}
peerDependencies:
'@bufbuild/protobuf': ^1.4.2
'@connectrpc/connect': 1.4.0
dependencies:
'@bufbuild/protobuf': 1.10.0
'@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0)
dev: false
/@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0):
resolution: {integrity: sha512-vZeOkKaAjyV4+RH3+rJZIfDFJAfr+7fyYr6sLDKbYX3uuTVszhFe9/YKf5DNqrDb5cKdKVlYkGn6DTDqMitAnA==}
peerDependencies:
'@bufbuild/protobuf': ^1.4.2
dependencies:
'@bufbuild/protobuf': 1.10.0
dev: false
/@cspotcode/source-map-support@0.8.1:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
@ -24067,14 +24118,14 @@ packages:
react: 18.1.0
scheduler: 0.22.0
/react-dom@18.2.0(react@18.2.0):
resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
/react-dom@18.3.1(react@18.3.1):
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
peerDependencies:
react: ^18.2.0
react: ^18.3.1
dependencies:
loose-envify: 1.4.0
react: 18.2.0
scheduler: 0.23.0
react: 18.3.1
scheduler: 0.23.2
dev: false
/react-draggable@4.4.3(react-dom@18.1.0)(react@18.1.0):
@ -24522,8 +24573,8 @@ packages:
/react-zdog@1.2.2:
resolution: {integrity: sha512-Ix7ALha91aOEwiHuxumCeYbARS5XNpc/w0v145oGkM6poF/CvhKJwzLhM5sEZbtrghMA+psAhOJkCTzJoseicA==}
dependencies:
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
resize-observer-polyfill: 1.5.1
dev: false
@ -24533,8 +24584,8 @@ packages:
dependencies:
loose-envify: 1.4.0
/react@18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
/react@18.3.1:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'}
dependencies:
loose-envify: 1.4.0
@ -25276,8 +25327,8 @@ packages:
dependencies:
loose-envify: 1.4.0
/scheduler@0.23.0:
resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
/scheduler@0.23.2:
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
dependencies:
loose-envify: 1.4.0
dev: false
@ -25815,6 +25866,10 @@ packages:
/sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
/stable-hash@0.0.4:
resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==}
dev: false
/stack-utils@2.0.6:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}