diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 7de4c46c91..04564c9aa1 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -19279,9 +19279,11 @@ const docTemplate = `{ "mcp-server-http", "workspace-build-updates", "nats_pubsub", - "minimum-implicit-member" + "minimum-implicit-member", + "ai-gateway-cost-control" ], "x-enum-comments": { + "ExperimentAIGatewayCostControl": "Enables AI Gateway cost control functionality.", "ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.", "ExperimentExample": "This isn't used for anything.", "ExperimentMCPServerHTTP": "Enables the MCP HTTP server functionality.", @@ -19301,7 +19303,8 @@ const docTemplate = `{ "Enables the MCP HTTP server functionality.", "Enables publishing workspace build updates to the all builds pubsub channel.", "Enables embedded NATS pubsub.", - "Allows organizations to deviate from the default organization-member roles, in support of Gateway Accounts." + "Allows organizations to deviate from the default organization-member roles, in support of Gateway Accounts.", + "Enables AI Gateway cost control functionality." ], "x-enum-varnames": [ "ExperimentExample", @@ -19312,7 +19315,8 @@ const docTemplate = `{ "ExperimentMCPServerHTTP", "ExperimentWorkspaceBuildUpdates", "ExperimentNATSPubsub", - "ExperimentMinimumImplicitMember" + "ExperimentMinimumImplicitMember", + "ExperimentAIGatewayCostControl" ] }, "codersdk.ExternalAPIKeyScopes": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index b7887f101c..ee41261e16 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -17493,9 +17493,11 @@ "mcp-server-http", "workspace-build-updates", "nats_pubsub", - "minimum-implicit-member" + "minimum-implicit-member", + "ai-gateway-cost-control" ], "x-enum-comments": { + "ExperimentAIGatewayCostControl": "Enables AI Gateway cost control functionality.", "ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.", "ExperimentExample": "This isn't used for anything.", "ExperimentMCPServerHTTP": "Enables the MCP HTTP server functionality.", @@ -17515,7 +17517,8 @@ "Enables the MCP HTTP server functionality.", "Enables publishing workspace build updates to the all builds pubsub channel.", "Enables embedded NATS pubsub.", - "Allows organizations to deviate from the default organization-member roles, in support of Gateway Accounts." + "Allows organizations to deviate from the default organization-member roles, in support of Gateway Accounts.", + "Enables AI Gateway cost control functionality." ], "x-enum-varnames": [ "ExperimentExample", @@ -17526,7 +17529,8 @@ "ExperimentMCPServerHTTP", "ExperimentWorkspaceBuildUpdates", "ExperimentNATSPubsub", - "ExperimentMinimumImplicitMember" + "ExperimentMinimumImplicitMember", + "ExperimentAIGatewayCostControl" ] }, "codersdk.ExternalAPIKeyScopes": { diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 5d3ffe8294..21d7d3d883 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -5108,6 +5108,7 @@ const ( ExperimentWorkspaceBuildUpdates Experiment = "workspace-build-updates" // Enables publishing workspace build updates to the all builds pubsub channel. ExperimentNATSPubsub Experiment = "nats_pubsub" // Enables embedded NATS pubsub. ExperimentMinimumImplicitMember Experiment = "minimum-implicit-member" // Allows organizations to deviate from the default organization-member roles, in support of Gateway Accounts. + ExperimentAIGatewayCostControl Experiment = "ai-gateway-cost-control" // Enables AI Gateway cost control functionality. ) func (e Experiment) DisplayName() string { @@ -5130,6 +5131,8 @@ func (e Experiment) DisplayName() string { return "NATS Pubsub" case ExperimentMinimumImplicitMember: return "Gateway Accounts (minimum implicit member)" + case ExperimentAIGatewayCostControl: + return "AI Gateway Cost Control" default: // Split on hyphen and convert to title case // e.g. "mcp-server-http" -> "Mcp Server Http" @@ -5149,6 +5152,7 @@ var ExperimentsKnown = Experiments{ ExperimentNATSPubsub, ExperimentWorkspaceBuildUpdates, ExperimentMinimumImplicitMember, + ExperimentAIGatewayCostControl, } // ExperimentsSafe should include all experiments that are safe for diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index 4999854660..7fa0ae3dd7 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -6961,9 +6961,9 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o #### Enumerated Values -| Value(s) | -|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `auto-fill-parameters`, `example`, `mcp-server-http`, `minimum-implicit-member`, `nats_pubsub`, `notifications`, `oauth2`, `workspace-build-updates`, `workspace-usage` | +| Value(s) | +|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `ai-gateway-cost-control`, `auto-fill-parameters`, `example`, `mcp-server-http`, `minimum-implicit-member`, `nats_pubsub`, `notifications`, `oauth2`, `workspace-build-updates`, `workspace-usage` | ## codersdk.ExternalAPIKeyScopes diff --git a/enterprise/coderd/aibridge_test.go b/enterprise/coderd/aibridge_test.go index 6502cf74a1..86cb319047 100644 --- a/enterprise/coderd/aibridge_test.go +++ b/enterprise/coderd/aibridge_test.go @@ -2706,6 +2706,7 @@ func TestUserAIBudgetOverrideRoleAccess(t *testing.T) { dv := coderdtest.DeploymentValues(t) dv.AI.BridgeConfig.Enabled = serpent.Bool(true) + dv.Experiments = []string{string(codersdk.ExperimentAIGatewayCostControl)} ownerClient, owner := coderdenttest.New(t, &coderdenttest.Options{ Options: &coderdtest.Options{DeploymentValues: dv}, LicenseOptions: &coderdenttest.LicenseOptions{ @@ -2803,6 +2804,7 @@ func TestUserAIBudgetOverrideDeletedOnMembershipRemoval(t *testing.T) { dv := coderdtest.DeploymentValues(t) dv.AI.BridgeConfig.Enabled = serpent.Bool(true) + dv.Experiments = []string{string(codersdk.ExperimentAIGatewayCostControl)} ownerClient, owner := coderdenttest.New(t, &coderdenttest.Options{ Options: &coderdtest.Options{DeploymentValues: dv}, LicenseOptions: &coderdenttest.LicenseOptions{ @@ -2892,6 +2894,7 @@ func setupUserAIBudgetOverrideTest(t *testing.T) (adminClient *codersdk.Client, dv := coderdtest.DeploymentValues(t) dv.AI.BridgeConfig.Enabled = serpent.Bool(true) + dv.Experiments = []string{string(codersdk.ExperimentAIGatewayCostControl)} ownerClient, owner := coderdenttest.New(t, &coderdenttest.Options{ Options: &coderdtest.Options{DeploymentValues: dv}, LicenseOptions: &coderdenttest.LicenseOptions{ @@ -2930,6 +2933,7 @@ func setupUserAIBudgetOverrideAuditTest(t *testing.T) (database.Store, *codersdk ) dv := coderdtest.DeploymentValues(t) dv.AI.BridgeConfig.Enabled = serpent.Bool(true) + dv.Experiments = []string{string(codersdk.ExperimentAIGatewayCostControl)} ownerClient, owner := coderdenttest.New(t, &coderdenttest.Options{ AuditLogging: true, Options: &coderdtest.Options{ diff --git a/enterprise/coderd/coderd.go b/enterprise/coderd/coderd.go index f82fb430ae..40d1e7f097 100644 --- a/enterprise/coderd/coderd.go +++ b/enterprise/coderd/coderd.go @@ -612,6 +612,8 @@ func New(ctx context.Context, options *Options) (_ *API, err error) { r.Route("/users/{user}/ai/budget", func(r chi.Router) { // AI cost controls are a paid feature (AI Governance add-on). r.Use( + // TODO(AIGOV-443): remove once AI Gateway cost control functionality is stable. + httpmw.RequireExperiment(api.AGPL.Experiments, codersdk.ExperimentAIGatewayCostControl), api.RequireFeatureMW(codersdk.FeatureAIBridge), apiKeyMiddleware, httpmw.ExtractUserParam(options.Database), diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index fe2e574f4f..1604e358ee 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -4347,6 +4347,7 @@ export const EntitlementsWarningHeader = "X-Coder-Entitlements-Warning"; // From codersdk/deployment.go export type Experiment = + | "ai-gateway-cost-control" | "auto-fill-parameters" | "example" | "mcp-server-http" @@ -4358,6 +4359,7 @@ export type Experiment = | "workspace-usage"; export const Experiments: Experiment[] = [ + "ai-gateway-cost-control", "auto-fill-parameters", "example", "mcp-server-http",