From 130eb7afd6ddf2e5c576cda32810844e0dac60c0 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 27 Oct 2025 21:45:00 +0200 Subject: [PATCH 1/3] feat: AWS Bedrock support Signed-off-by: Danny Kopping --- cli/testdata/server-config.yaml.golden | 18 +++++ coderd/apidoc/docs.go | 23 ++++++ coderd/apidoc/swagger.json | 23 ++++++ codersdk/deployment.go | 70 ++++++++++++++++++- docs/reference/api/general.md | 7 ++ docs/reference/api/schemas.md | 51 ++++++++++++++ enterprise/cli/aibridged.go | 21 +++++- .../x/aibridged/aibridged_integration_test.go | 2 +- enterprise/x/aibridged/aibridged_test.go | 4 +- go.mod | 1 + go.sum | 2 + site/src/api/typesGenerated.ts | 10 +++ 12 files changed, 223 insertions(+), 9 deletions(-) diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index 40666c10e8394..1fd543a2361ee 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -730,3 +730,21 @@ aibridge: # The key to authenticate against the Anthropic API. # (default: , type: string) key: "" + # The AWS Bedrock API region. + # (default: , type: string) + bedrock_region: "" + # The access key to authenticate against the AWS Bedrock API. + # (default: , type: string) + bedrock_access_key: "" + # The access key secret to use with the access key to authenticate against the AWS + # Bedrock API. + # (default: , type: string) + bedrock_access_key_secret: "" + # The model to use when making requests to the AWS Bedrock API. + # (default: global.anthropic.claude-sonnet-4-5-20250929-v1:0, type: string) + bedrock_model: global.anthropic.claude-sonnet-4-5-20250929-v1:0 + # The small fast model to use when making requests to the AWS Bedrock API. Claude + # Code uses Haiku-class models to perform background tasks. See + # https://docs.claude.com/en/docs/claude-code/settings#environment-variables. + # (default: global.anthropic.claude-haiku-4-5-20251001-v1:0, type: string) + bedrock_small_fast_model: global.anthropic.claude-haiku-4-5-20251001-v1:0 diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index c0cf84224c764..59080a2980ce5 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -11668,12 +11668,35 @@ const docTemplate = `{ } } }, + "codersdk.AIBridgeBedrockConfig": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + }, + "access_key_secret": { + "type": "string" + }, + "model": { + "type": "string" + }, + "region": { + "type": "string" + }, + "small_fast_model": { + "type": "string" + } + } + }, "codersdk.AIBridgeConfig": { "type": "object", "properties": { "anthropic": { "$ref": "#/definitions/codersdk.AIBridgeAnthropicConfig" }, + "bedrock": { + "$ref": "#/definitions/codersdk.AIBridgeBedrockConfig" + }, "enabled": { "type": "boolean" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 0c7a865112cff..9d87ae0014568 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -10364,12 +10364,35 @@ } } }, + "codersdk.AIBridgeBedrockConfig": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + }, + "access_key_secret": { + "type": "string" + }, + "model": { + "type": "string" + }, + "region": { + "type": "string" + }, + "small_fast_model": { + "type": "string" + } + } + }, "codersdk.AIBridgeConfig": { "type": "object", "properties": { "anthropic": { "$ref": "#/definitions/codersdk.AIBridgeAnthropicConfig" }, + "bedrock": { + "$ref": "#/definitions/codersdk.AIBridgeBedrockConfig" + }, "enabled": { "type": "boolean" }, diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 2f6f6bba03697..05ddcfcfc1d39 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -3280,18 +3280,73 @@ Write out the current server config as YAML to stdout.`, Value: &c.AI.BridgeConfig.Anthropic.BaseURL, Default: "https://api.anthropic.com/", Group: &deploymentGroupAIBridge, - YAML: "base_url", + YAML: "base_url", // TODO: this needs to be namespaced to Anthropic, but may cause BC breaks. Hidden: true, }, { - Name: "AIBridge Anthropic KEY", + Name: "AIBridge Anthropic Key", Description: "The key to authenticate against the Anthropic API.", Flag: "aibridge-anthropic-key", Env: "CODER_AIBRIDGE_ANTHROPIC_KEY", Value: &c.AI.BridgeConfig.Anthropic.Key, Default: "", Group: &deploymentGroupAIBridge, - YAML: "key", + YAML: "key", // TODO: this needs to be namespaced to Anthropic, but may cause BC breaks. + Hidden: true, + }, + { + Name: "AIBridge Bedrock Region", + Description: "The AWS Bedrock API region.", + Flag: "aibridge-bedrock-region", + Env: "CODER_AIBRIDGE_BEDROCK_REGION", + Value: &c.AI.BridgeConfig.Bedrock.Region, + Default: "", + Group: &deploymentGroupAIBridge, + YAML: "bedrock_region", + Hidden: true, + }, + { + Name: "AIBridge Bedrock Access Key", + Description: "The access key to authenticate against the AWS Bedrock API.", + Flag: "aibridge-bedrock-access-key", + Env: "CODER_AIBRIDGE_BEDROCK_ACCESS_KEY", + Value: &c.AI.BridgeConfig.Bedrock.AccessKey, + Default: "", + Group: &deploymentGroupAIBridge, + YAML: "bedrock_access_key", + Hidden: true, + }, + { + Name: "AIBridge Bedrock Access Key Secret", + Description: "The access key secret to use with the access key to authenticate against the AWS Bedrock API.", + Flag: "aibridge-bedrock-access-key-secret", + Env: "CODER_AIBRIDGE_BEDROCK_ACCESS_KEY_SECRET", + Value: &c.AI.BridgeConfig.Bedrock.AccessKeySecret, + Default: "", + Group: &deploymentGroupAIBridge, + YAML: "bedrock_access_key_secret", + Hidden: true, + }, + { + Name: "AIBridge Bedrock Model", + Description: "The model to use when making requests to the AWS Bedrock API.", + Flag: "aibridge-bedrock-model", + Env: "CODER_AIBRIDGE_BEDROCK_MODEL", + Value: &c.AI.BridgeConfig.Bedrock.Model, + Default: "global.anthropic.claude-sonnet-4-5-20250929-v1:0", // See https://docs.claude.com/en/api/claude-on-amazon-bedrock#accessing-bedrock. + Group: &deploymentGroupAIBridge, + YAML: "bedrock_model", + Hidden: true, + }, + { + Name: "AIBridge Bedrock Small Fast Model", + Description: "The small fast model to use when making requests to the AWS Bedrock API. Claude Code uses Haiku-class models to perform background tasks. See https://docs.claude.com/en/docs/claude-code/settings#environment-variables.", + Flag: "aibridge-bedrock-small-fastmodel", + Env: "CODER_AIBRIDGE_BEDROCK_SMALL_FAST_MODEL", + Value: &c.AI.BridgeConfig.Bedrock.SmallFastModel, + Default: "global.anthropic.claude-haiku-4-5-20251001-v1:0", // See https://docs.claude.com/en/api/claude-on-amazon-bedrock#accessing-bedrock. + Group: &deploymentGroupAIBridge, + YAML: "bedrock_small_fast_model", Hidden: true, }, { @@ -3316,6 +3371,7 @@ type AIBridgeConfig struct { Enabled serpent.Bool `json:"enabled" typescript:",notnull"` OpenAI AIBridgeOpenAIConfig `json:"openai" typescript:",notnull"` Anthropic AIBridgeAnthropicConfig `json:"anthropic" typescript:",notnull"` + Bedrock AIBridgeBedrockConfig `json:"bedrock" typescript:",notnull"` } type AIBridgeOpenAIConfig struct { @@ -3328,6 +3384,14 @@ type AIBridgeAnthropicConfig struct { Key serpent.String `json:"key" typescript:",notnull"` } +type AIBridgeBedrockConfig struct { + Region serpent.String `json:"region" typescript:",notnull"` + AccessKey serpent.String `json:"access_key" typescript:",notnull"` + AccessKeySecret serpent.String `json:"access_key_secret" typescript:",notnull"` + Model serpent.String `json:"model" typescript:",notnull"` + SmallFastModel serpent.String `json:"small_fast_model" typescript:",notnull"` +} + type AIConfig struct { BridgeConfig AIBridgeConfig `json:"bridge,omitempty"` } diff --git a/docs/reference/api/general.md b/docs/reference/api/general.md index ad15e8fac2ae3..5718979ae86c2 100644 --- a/docs/reference/api/general.md +++ b/docs/reference/api/general.md @@ -167,6 +167,13 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ "base_url": "string", "key": "string" }, + "bedrock": { + "access_key": "string", + "access_key_secret": "string", + "model": "string", + "region": "string", + "small_fast_model": "string" + }, "enabled": true, "openai": { "base_url": "string", diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index cb3345e67c122..e7121bfb8ec19 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -351,6 +351,28 @@ | `base_url` | string | false | | | | `key` | string | false | | | +## codersdk.AIBridgeBedrockConfig + +```json +{ + "access_key": "string", + "access_key_secret": "string", + "model": "string", + "region": "string", + "small_fast_model": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +|---------------------|--------|----------|--------------|-------------| +| `access_key` | string | false | | | +| `access_key_secret` | string | false | | | +| `model` | string | false | | | +| `region` | string | false | | | +| `small_fast_model` | string | false | | | + ## codersdk.AIBridgeConfig ```json @@ -359,6 +381,13 @@ "base_url": "string", "key": "string" }, + "bedrock": { + "access_key": "string", + "access_key_secret": "string", + "model": "string", + "region": "string", + "small_fast_model": "string" + }, "enabled": true, "openai": { "base_url": "string", @@ -372,6 +401,7 @@ | Name | Type | Required | Restrictions | Description | |-------------|----------------------------------------------------------------------|----------|--------------|-------------| | `anthropic` | [codersdk.AIBridgeAnthropicConfig](#codersdkaibridgeanthropicconfig) | false | | | +| `bedrock` | [codersdk.AIBridgeBedrockConfig](#codersdkaibridgebedrockconfig) | false | | | | `enabled` | boolean | false | | | | `openai` | [codersdk.AIBridgeOpenAIConfig](#codersdkaibridgeopenaiconfig) | false | | | @@ -654,6 +684,13 @@ "base_url": "string", "key": "string" }, + "bedrock": { + "access_key": "string", + "access_key_secret": "string", + "model": "string", + "region": "string", + "small_fast_model": "string" + }, "enabled": true, "openai": { "base_url": "string", @@ -2787,6 +2824,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "base_url": "string", "key": "string" }, + "bedrock": { + "access_key": "string", + "access_key_secret": "string", + "model": "string", + "region": "string", + "small_fast_model": "string" + }, "enabled": true, "openai": { "base_url": "string", @@ -3294,6 +3338,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "base_url": "string", "key": "string" }, + "bedrock": { + "access_key": "string", + "access_key_secret": "string", + "model": "string", + "region": "string", + "small_fast_model": "string" + }, "enabled": true, "openai": { "base_url": "string", diff --git a/enterprise/cli/aibridged.go b/enterprise/cli/aibridged.go index 9e59327039fc3..17bb5ebe681fa 100644 --- a/enterprise/cli/aibridged.go +++ b/enterprise/cli/aibridged.go @@ -8,6 +8,7 @@ import ( "golang.org/x/xerrors" "github.com/coder/aibridge" + "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd" "github.com/coder/coder/v2/enterprise/x/aibridged" ) @@ -20,14 +21,14 @@ func newAIBridgeDaemon(coderAPI *coderd.API) (*aibridged.Server, error) { // Setup supported providers. providers := []aibridge.Provider{ - aibridge.NewOpenAIProvider(aibridge.ProviderConfig{ + aibridge.NewOpenAIProvider(aibridge.OpenAIConfig{ BaseURL: coderAPI.DeploymentValues.AI.BridgeConfig.OpenAI.BaseURL.String(), Key: coderAPI.DeploymentValues.AI.BridgeConfig.OpenAI.Key.String(), }), - aibridge.NewAnthropicProvider(aibridge.ProviderConfig{ + aibridge.NewAnthropicProvider(aibridge.AnthropicConfig{ BaseURL: coderAPI.DeploymentValues.AI.BridgeConfig.Anthropic.BaseURL.String(), Key: coderAPI.DeploymentValues.AI.BridgeConfig.Anthropic.Key.String(), - }), + }, getBedrockConfig(coderAPI.DeploymentValues.AI.BridgeConfig.Bedrock)), } // Create pool for reusable stateful [aibridge.RequestBridge] instances (one per user). @@ -45,3 +46,17 @@ func newAIBridgeDaemon(coderAPI *coderd.API) (*aibridged.Server, error) { } return srv, nil } + +func getBedrockConfig(cfg codersdk.AIBridgeBedrockConfig) *aibridge.AWSBedrockConfig { + if cfg.Region.String() == "" && cfg.AccessKey.String() == "" && cfg.AccessKeySecret.String() == "" { + return nil + } + + return &aibridge.AWSBedrockConfig{ + Region: cfg.Region.String(), + AccessKey: cfg.AccessKey.String(), + AccessKeySecret: cfg.AccessKeySecret.String(), + Model: cfg.Model.String(), + SmallFastModel: cfg.SmallFastModel.String(), + } +} diff --git a/enterprise/x/aibridged/aibridged_integration_test.go b/enterprise/x/aibridged/aibridged_integration_test.go index 69d7627e04c5f..45d47bd1b3507 100644 --- a/enterprise/x/aibridged/aibridged_integration_test.go +++ b/enterprise/x/aibridged/aibridged_integration_test.go @@ -164,7 +164,7 @@ func TestIntegration(t *testing.T) { require.NoError(t, err) logger := testutil.Logger(t) - providers := []aibridge.Provider{aibridge.NewOpenAIProvider(aibridge.ProviderConfig{BaseURL: mockOpenAI.URL})} + providers := []aibridge.Provider{aibridge.NewOpenAIProvider(aibridge.OpenAIConfig{BaseURL: mockOpenAI.URL})} pool, err := aibridged.NewCachedBridgePool(aibridged.DefaultPoolOptions, providers, logger) require.NoError(t, err) diff --git a/enterprise/x/aibridged/aibridged_test.go b/enterprise/x/aibridged/aibridged_test.go index 84e493090563c..967e9aac2bce3 100644 --- a/enterprise/x/aibridged/aibridged_test.go +++ b/enterprise/x/aibridged/aibridged_test.go @@ -288,8 +288,8 @@ func TestRouting(t *testing.T) { client := mock.NewMockDRPCClient(ctrl) providers := []aibridge.Provider{ - aibridge.NewOpenAIProvider(aibridge.ProviderConfig{BaseURL: openaiSrv.URL}), - aibridge.NewAnthropicProvider(aibridge.ProviderConfig{BaseURL: antSrv.URL}), + aibridge.NewOpenAIProvider(aibridge.OpenAIConfig{BaseURL: openaiSrv.URL}), + aibridge.NewAnthropicProvider(aibridge.AnthropicConfig{BaseURL: antSrv.URL}, nil), } pool, err := aibridged.NewCachedBridgePool(aibridged.DefaultPoolOptions, providers, logger) require.NoError(t, err) diff --git a/go.mod b/go.mod index 3f4bf60c15ce3..cc76993e41e29 100644 --- a/go.mod +++ b/go.mod @@ -509,6 +509,7 @@ require ( github.com/aquasecurity/trivy v0.61.1-0.20250407075540-f1329c7ea1aa // indirect github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169 // indirect github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/buger/jsonparser v1.1.1 // indirect diff --git a/go.sum b/go.sum index ee37485533080..b772d942cd900 100644 --- a/go.sum +++ b/go.sum @@ -764,6 +764,8 @@ github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I= github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= github.com/aws/aws-sdk-go-v2/config v1.31.3 h1:RIb3yr/+PZ18YYNe6MDiG/3jVoJrPmdoCARwNkMGvco= github.com/aws/aws-sdk-go-v2/config v1.31.3/go.mod h1:jjgx1n7x0FAKl6TnakqrpkHWWKcX3xfWtdnIJs5K9CE= github.com/aws/aws-sdk-go-v2/credentials v1.18.7 h1:zqg4OMrKj+t5HlswDApgvAHjxKtlduKS7KicXB+7RLg= diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 5e9bc73975da6..aa772274f3cd0 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -16,11 +16,21 @@ export interface AIBridgeAnthropicConfig { readonly key: string; } +// From codersdk/deployment.go +export interface AIBridgeBedrockConfig { + readonly region: string; + readonly access_key: string; + readonly access_key_secret: string; + readonly model: string; + readonly small_fast_model: string; +} + // From codersdk/deployment.go export interface AIBridgeConfig { readonly enabled: boolean; readonly openai: AIBridgeOpenAIConfig; readonly anthropic: AIBridgeAnthropicConfig; + readonly bedrock: AIBridgeBedrockConfig; } // From codersdk/aibridge.go From 1ea6a2398f161a681e378f085f937ef24c91fa5c Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Tue, 28 Oct 2025 05:06:33 +0200 Subject: [PATCH 2/3] chore: aibridge v0.1.6 Signed-off-by: Danny Kopping --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index cc76993e41e29..d87c8300234c8 100644 --- a/go.mod +++ b/go.mod @@ -476,7 +476,7 @@ require ( github.com/anthropics/anthropic-sdk-go v1.13.0 github.com/brianvoe/gofakeit/v7 v7.8.0 github.com/coder/agentapi-sdk-go v0.0.0-20250505131810-560d1d88d225 - github.com/coder/aibridge v0.1.5 + github.com/coder/aibridge v0.1.6 github.com/coder/aisdk-go v0.0.9 github.com/coder/boundary v1.0.1-0.20250925154134-55a44f2a7945 github.com/coder/preview v1.0.4 diff --git a/go.sum b/go.sum index b772d942cd900..2655cb93f2cbd 100644 --- a/go.sum +++ b/go.sum @@ -917,8 +917,8 @@ github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/coder/agentapi-sdk-go v0.0.0-20250505131810-560d1d88d225 h1:tRIViZ5JRmzdOEo5wUWngaGEFBG8OaE1o2GIHN5ujJ8= github.com/coder/agentapi-sdk-go v0.0.0-20250505131810-560d1d88d225/go.mod h1:rNLVpYgEVeu1Zk29K64z6Od8RBP9DwqCu9OfCzh8MR4= -github.com/coder/aibridge v0.1.5 h1:uSrltfLZWF2qOaq9RDzJW/26Ow1wMFwcwObBM0WikME= -github.com/coder/aibridge v0.1.5/go.mod h1:Q5MCfKMcKYmYl4qH1Zd0rltmPaUBPKFvIPs2k9q6qeY= +github.com/coder/aibridge v0.1.6 h1:Ax9hfAQeg+vLeE9M/IMmARuBuGyCuFdMw8bpy72/fD8= +github.com/coder/aibridge v0.1.6/go.mod h1:7GhrLbzf6uM3sCA7OPaDzvq9QNrCjNuzMy+WgipYwfQ= github.com/coder/aisdk-go v0.0.9 h1:Vzo/k2qwVGLTR10ESDeP2Ecek1SdPfZlEjtTfMveiVo= github.com/coder/aisdk-go v0.0.9/go.mod h1:KF6/Vkono0FJJOtWtveh5j7yfNrSctVTpwgweYWSp5M= github.com/coder/boundary v1.0.1-0.20250925154134-55a44f2a7945 h1:hDUf02kTX8EGR3+5B+v5KdYvORs4YNfDPci0zCs+pC0= From 85452f0683aea161181c8bb8eaa134deb70fd499 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Tue, 28 Oct 2025 05:25:58 +0200 Subject: [PATCH 3/3] chore: fix yaml names Signed-off-by: Danny Kopping --- cli/testdata/server-config.yaml.golden | 4 ++-- codersdk/deployment.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index 1fd543a2361ee..cbabf0474f291 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -726,10 +726,10 @@ aibridge: openai_key: "" # The base URL of the Anthropic API. # (default: https://api.anthropic.com/, type: string) - base_url: https://api.anthropic.com/ + anthropic_base_url: https://api.anthropic.com/ # The key to authenticate against the Anthropic API. # (default: , type: string) - key: "" + anthropic_key: "" # The AWS Bedrock API region. # (default: , type: string) bedrock_region: "" diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 05ddcfcfc1d39..97bbb13bedbc7 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -3280,7 +3280,7 @@ Write out the current server config as YAML to stdout.`, Value: &c.AI.BridgeConfig.Anthropic.BaseURL, Default: "https://api.anthropic.com/", Group: &deploymentGroupAIBridge, - YAML: "base_url", // TODO: this needs to be namespaced to Anthropic, but may cause BC breaks. + YAML: "anthropic_base_url", Hidden: true, }, { @@ -3291,7 +3291,7 @@ Write out the current server config as YAML to stdout.`, Value: &c.AI.BridgeConfig.Anthropic.Key, Default: "", Group: &deploymentGroupAIBridge, - YAML: "key", // TODO: this needs to be namespaced to Anthropic, but may cause BC breaks. + YAML: "anthropic_key", Hidden: true, }, {