chore: add aibridge configs & experiment (#19793)

This commit is contained in:
Danny Kopping
2025-09-16 11:45:23 +02:00
committed by GitHub
parent 2695bb418a
commit 8487216548
7 changed files with 355 additions and 4 deletions
+17
View File
@@ -713,3 +713,20 @@ workspace_prebuilds:
# limit; disabled when set to zero.
# (default: 3, type: int)
failure_hard_limit: 3
aibridge:
# Whether to start an in-memory aibridged instance ("aibridge" experiment must be
# enabled, too).
# (default: false, type: bool)
enabled: false
# The base URL of the OpenAI API.
# (default: https://api.openai.com/v1/, type: string)
openai_base_url: https://api.openai.com/v1/
# The key to authenticate against the OpenAI API.
# (default: <unset>, type: string)
openai_key: ""
# The base URL of the Anthropic API.
# (default: https://api.anthropic.com/, type: string)
base_url: https://api.anthropic.com/
# The key to authenticate against the Anthropic API.
# (default: <unset>, type: string)
key: ""
+52 -2
View File
@@ -11175,6 +11175,50 @@ const docTemplate = `{
}
}
},
"codersdk.AIBridgeAnthropicConfig": {
"type": "object",
"properties": {
"base_url": {
"type": "string"
},
"key": {
"type": "string"
}
}
},
"codersdk.AIBridgeConfig": {
"type": "object",
"properties": {
"anthropic": {
"$ref": "#/definitions/codersdk.AIBridgeAnthropicConfig"
},
"enabled": {
"type": "boolean"
},
"openai": {
"$ref": "#/definitions/codersdk.AIBridgeOpenAIConfig"
}
}
},
"codersdk.AIBridgeOpenAIConfig": {
"type": "object",
"properties": {
"base_url": {
"type": "string"
},
"key": {
"type": "string"
}
}
},
"codersdk.AIConfig": {
"type": "object",
"properties": {
"bridge": {
"$ref": "#/definitions/codersdk.AIBridgeConfig"
}
}
},
"codersdk.APIKey": {
"type": "object",
"required": [
@@ -12811,6 +12855,9 @@ const docTemplate = `{
"agent_stat_refresh_interval": {
"type": "integer"
},
"ai": {
"$ref": "#/definitions/codersdk.AIConfig"
},
"allow_workspace_renames": {
"type": "boolean"
},
@@ -13138,9 +13185,11 @@ const docTemplate = `{
"web-push",
"oauth2",
"mcp-server-http",
"workspace-sharing"
"workspace-sharing",
"aibridge"
],
"x-enum-comments": {
"ExperimentAIBridge": "Enables AI Bridge 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.",
@@ -13158,7 +13207,8 @@ const docTemplate = `{
"ExperimentWebPush",
"ExperimentOAuth2",
"ExperimentMCPServerHTTP",
"ExperimentWorkspaceSharing"
"ExperimentWorkspaceSharing",
"ExperimentAIBridge"
]
},
"codersdk.ExternalAgentCredentials": {
+52 -2
View File
@@ -9909,6 +9909,50 @@
}
}
},
"codersdk.AIBridgeAnthropicConfig": {
"type": "object",
"properties": {
"base_url": {
"type": "string"
},
"key": {
"type": "string"
}
}
},
"codersdk.AIBridgeConfig": {
"type": "object",
"properties": {
"anthropic": {
"$ref": "#/definitions/codersdk.AIBridgeAnthropicConfig"
},
"enabled": {
"type": "boolean"
},
"openai": {
"$ref": "#/definitions/codersdk.AIBridgeOpenAIConfig"
}
}
},
"codersdk.AIBridgeOpenAIConfig": {
"type": "object",
"properties": {
"base_url": {
"type": "string"
},
"key": {
"type": "string"
}
}
},
"codersdk.AIConfig": {
"type": "object",
"properties": {
"bridge": {
"$ref": "#/definitions/codersdk.AIBridgeConfig"
}
}
},
"codersdk.APIKey": {
"type": "object",
"required": [
@@ -11454,6 +11498,9 @@
"agent_stat_refresh_interval": {
"type": "integer"
},
"ai": {
"$ref": "#/definitions/codersdk.AIConfig"
},
"allow_workspace_renames": {
"type": "boolean"
},
@@ -11774,9 +11821,11 @@
"web-push",
"oauth2",
"mcp-server-http",
"workspace-sharing"
"workspace-sharing",
"aibridge"
],
"x-enum-comments": {
"ExperimentAIBridge": "Enables AI Bridge 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.",
@@ -11794,7 +11843,8 @@
"ExperimentWebPush",
"ExperimentOAuth2",
"ExperimentMCPServerHTTP",
"ExperimentWorkspaceSharing"
"ExperimentWorkspaceSharing",
"ExperimentAIBridge"
]
},
"codersdk.ExternalAgentCredentials": {
+86
View File
@@ -500,6 +500,7 @@ type DeploymentValues struct {
WorkspaceHostnameSuffix serpent.String `json:"workspace_hostname_suffix,omitempty" typescript:",notnull"`
Prebuilds PrebuildsConfig `json:"workspace_prebuilds,omitempty" typescript:",notnull"`
HideAITasks serpent.Bool `json:"hide_ai_tasks,omitempty" typescript:",notnull"`
AI AIConfig `json:"ai,omitempty"`
Config serpent.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"`
WriteConfig serpent.Bool `json:"write_config,omitempty" typescript:",notnull"`
@@ -1163,6 +1164,10 @@ func (c *DeploymentValues) Options() serpent.OptionSet {
Parent: &deploymentGroupNotifications,
YAML: "inbox",
}
deploymentGroupAIBridge = serpent.Group{
Name: "AIBridge",
YAML: "aibridge",
}
)
httpAddress := serpent.Option{
@@ -3223,11 +3228,88 @@ Write out the current server config as YAML to stdout.`,
Group: &deploymentGroupClient,
YAML: "hideAITasks",
},
// AIBridge Options
{
Name: "AIBridge Enabled",
Description: fmt.Sprintf("Whether to start an in-memory aibridged instance (%q experiment must be enabled, too).", ExperimentAIBridge),
Flag: "aibridge-enabled",
Env: "CODER_AIBRIDGE_ENABLED",
Value: &c.AI.BridgeConfig.Enabled,
Default: "false",
Group: &deploymentGroupAIBridge,
YAML: "enabled",
Hidden: true,
},
{
Name: "AIBridge OpenAI Base URL",
Description: "The base URL of the OpenAI API.",
Flag: "aibridge-openai-base-url",
Env: "CODER_AIBRIDGE_OPENAI_BASE_URL",
Value: &c.AI.BridgeConfig.OpenAI.BaseURL,
Default: "https://api.openai.com/v1/",
Group: &deploymentGroupAIBridge,
YAML: "openai_base_url",
Hidden: true,
},
{
Name: "AIBridge OpenAI Key",
Description: "The key to authenticate against the OpenAI API.",
Flag: "aibridge-openai-key",
Env: "CODER_AIBRIDGE_OPENAI_KEY",
Value: &c.AI.BridgeConfig.OpenAI.Key,
Default: "",
Group: &deploymentGroupAIBridge,
YAML: "openai_key",
Hidden: true,
},
{
Name: "AIBridge Anthropic Base URL",
Description: "The base URL of the Anthropic API.",
Flag: "aibridge-anthropic-base-url",
Env: "CODER_AIBRIDGE_ANTHROPIC_BASE_URL",
Value: &c.AI.BridgeConfig.Anthropic.BaseURL,
Default: "https://api.anthropic.com/",
Group: &deploymentGroupAIBridge,
YAML: "base_url",
Hidden: true,
},
{
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",
Hidden: true,
},
}
return opts
}
type AIBridgeConfig struct {
Enabled serpent.Bool `json:"enabled" typescript:",notnull"`
OpenAI AIBridgeOpenAIConfig `json:"openai" typescript:",notnull"`
Anthropic AIBridgeAnthropicConfig `json:"anthropic" typescript:",notnull"`
}
type AIBridgeOpenAIConfig struct {
BaseURL serpent.String `json:"base_url" typescript:",notnull"`
Key serpent.String `json:"key" typescript:",notnull"`
}
type AIBridgeAnthropicConfig struct {
BaseURL serpent.String `json:"base_url" typescript:",notnull"`
Key serpent.String `json:"key" typescript:",notnull"`
}
type AIConfig struct {
BridgeConfig AIBridgeConfig `json:"bridge,omitempty"`
}
type SupportConfig struct {
Links serpent.Struct[[]LinkConfig] `json:"links" typescript:",notnull"`
}
@@ -3475,6 +3557,7 @@ const (
ExperimentOAuth2 Experiment = "oauth2" // Enables OAuth2 provider functionality.
ExperimentMCPServerHTTP Experiment = "mcp-server-http" // Enables the MCP HTTP server functionality.
ExperimentWorkspaceSharing Experiment = "workspace-sharing" // Enables updating workspace ACLs for sharing with users and groups.
ExperimentAIBridge Experiment = "aibridge" // Enables AI Bridge functionality.
)
func (e Experiment) DisplayName() string {
@@ -3495,6 +3578,8 @@ func (e Experiment) DisplayName() string {
return "MCP HTTP Server Functionality"
case ExperimentWorkspaceSharing:
return "Workspace Sharing"
case ExperimentAIBridge:
return "AI Bridge"
default:
// Split on hyphen and convert to title case
// e.g. "web-push" -> "Web Push", "mcp-server-http" -> "Mcp Server Http"
@@ -3513,6 +3598,7 @@ var ExperimentsKnown = Experiments{
ExperimentOAuth2,
ExperimentMCPServerHTTP,
ExperimentWorkspaceSharing,
ExperimentAIBridge,
}
// ExperimentsSafe should include all experiments that are safe for
+13
View File
@@ -161,6 +161,19 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \
"user": {}
},
"agent_stat_refresh_interval": 0,
"ai": {
"bridge": {
"anthropic": {
"base_url": "string",
"key": "string"
},
"enabled": true,
"openai": {
"base_url": "string",
"key": "string"
}
}
},
"allow_workspace_renames": true,
"autobuild_poll_interval": 0,
"browser_only": true,
+108
View File
@@ -335,6 +335,86 @@
| `groups` | array of [codersdk.Group](#codersdkgroup) | false | | |
| `users` | array of [codersdk.ReducedUser](#codersdkreduceduser) | false | | |
## codersdk.AIBridgeAnthropicConfig
```json
{
"base_url": "string",
"key": "string"
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `base_url` | string | false | | |
| `key` | string | false | | |
## codersdk.AIBridgeConfig
```json
{
"anthropic": {
"base_url": "string",
"key": "string"
},
"enabled": true,
"openai": {
"base_url": "string",
"key": "string"
}
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
|-------------|----------------------------------------------------------------------|----------|--------------|-------------|
| `anthropic` | [codersdk.AIBridgeAnthropicConfig](#codersdkaibridgeanthropicconfig) | false | | |
| `enabled` | boolean | false | | |
| `openai` | [codersdk.AIBridgeOpenAIConfig](#codersdkaibridgeopenaiconfig) | false | | |
## codersdk.AIBridgeOpenAIConfig
```json
{
"base_url": "string",
"key": "string"
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `base_url` | string | false | | |
| `key` | string | false | | |
## codersdk.AIConfig
```json
{
"bridge": {
"anthropic": {
"base_url": "string",
"key": "string"
},
"enabled": true,
"openai": {
"base_url": "string",
"key": "string"
}
}
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
|----------|----------------------------------------------------|----------|--------------|-------------|
| `bridge` | [codersdk.AIBridgeConfig](#codersdkaibridgeconfig) | false | | |
## codersdk.APIKey
```json
@@ -2185,6 +2265,19 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
"user": {}
},
"agent_stat_refresh_interval": 0,
"ai": {
"bridge": {
"anthropic": {
"base_url": "string",
"key": "string"
},
"enabled": true,
"openai": {
"base_url": "string",
"key": "string"
}
}
},
"allow_workspace_renames": true,
"autobuild_poll_interval": 0,
"browser_only": true,
@@ -2673,6 +2766,19 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
"user": {}
},
"agent_stat_refresh_interval": 0,
"ai": {
"bridge": {
"anthropic": {
"base_url": "string",
"key": "string"
},
"enabled": true,
"openai": {
"base_url": "string",
"key": "string"
}
}
},
"allow_workspace_renames": true,
"autobuild_poll_interval": 0,
"browser_only": true,
@@ -3052,6 +3158,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
| `address` | [serpent.HostPort](#serpenthostport) | false | | Deprecated: Use HTTPAddress or TLS.Address instead. |
| `agent_fallback_troubleshooting_url` | [serpent.URL](#serpenturl) | false | | |
| `agent_stat_refresh_interval` | integer | false | | |
| `ai` | [codersdk.AIConfig](#codersdkaiconfig) | false | | |
| `allow_workspace_renames` | boolean | false | | |
| `autobuild_poll_interval` | integer | false | | |
| `browser_only` | boolean | false | | |
@@ -3356,6 +3463,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
| `oauth2` |
| `mcp-server-http` |
| `workspace-sharing` |
| `aibridge` |
## codersdk.ExternalAgentCredentials
+27
View File
@@ -6,6 +6,30 @@ export interface ACLAvailable {
readonly groups: readonly Group[];
}
// From codersdk/deployment.go
export interface AIBridgeAnthropicConfig {
readonly base_url: string;
readonly key: string;
}
// From codersdk/deployment.go
export interface AIBridgeConfig {
readonly enabled: boolean;
readonly openai: AIBridgeOpenAIConfig;
readonly anthropic: AIBridgeAnthropicConfig;
}
// From codersdk/deployment.go
export interface AIBridgeOpenAIConfig {
readonly base_url: string;
readonly key: string;
}
// From codersdk/deployment.go
export interface AIConfig {
readonly bridge?: AIBridgeConfig;
}
// From codersdk/aitasks.go
export const AITaskPromptParameterName = "AI Prompt";
@@ -839,6 +863,7 @@ export interface DeploymentValues {
readonly workspace_hostname_suffix?: string;
readonly workspace_prebuilds?: PrebuildsConfig;
readonly hide_ai_tasks?: boolean;
readonly ai?: AIConfig;
readonly config?: string;
readonly write_config?: boolean;
readonly address?: string;
@@ -930,6 +955,7 @@ export const EntitlementsWarningHeader = "X-Coder-Entitlements-Warning";
// From codersdk/deployment.go
export type Experiment =
| "aibridge"
| "auto-fill-parameters"
| "example"
| "mcp-server-http"
@@ -940,6 +966,7 @@ export type Experiment =
| "workspace-usage";
export const Experiments: Experiment[] = [
"aibridge",
"auto-fill-parameters",
"example",
"mcp-server-http",