mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: initialize aibridged & mount API handler (#19798)
Addresses https://github.com/coder/internal/issues/987
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
//go:build !slim
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/aibridge"
|
||||
"github.com/coder/coder/v2/enterprise/coderd"
|
||||
"github.com/coder/coder/v2/enterprise/x/aibridged"
|
||||
)
|
||||
|
||||
func newAIBridgeDaemon(coderAPI *coderd.API) (*aibridged.Server, error) {
|
||||
ctx := context.Background()
|
||||
coderAPI.Logger.Debug(ctx, "starting in-memory aibridge daemon")
|
||||
|
||||
logger := coderAPI.Logger.Named("aibridged")
|
||||
|
||||
// Setup supported providers.
|
||||
providers := []aibridge.Provider{
|
||||
aibridge.NewOpenAIProvider(aibridge.ProviderConfig{
|
||||
BaseURL: coderAPI.DeploymentValues.AI.BridgeConfig.OpenAI.BaseURL.String(),
|
||||
Key: coderAPI.DeploymentValues.AI.BridgeConfig.OpenAI.Key.String(),
|
||||
}),
|
||||
aibridge.NewAnthropicProvider(aibridge.ProviderConfig{
|
||||
BaseURL: coderAPI.DeploymentValues.AI.BridgeConfig.Anthropic.BaseURL.String(),
|
||||
Key: coderAPI.DeploymentValues.AI.BridgeConfig.Anthropic.Key.String(),
|
||||
}),
|
||||
}
|
||||
|
||||
// Create pool for reusable stateful [aibridge.RequestBridge] instances (one per user).
|
||||
pool, err := aibridged.NewCachedBridgePool(aibridged.DefaultPoolOptions, providers, logger.Named("pool")) // TODO: configurable.
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("create request pool: %w", err)
|
||||
}
|
||||
|
||||
// Create daemon.
|
||||
srv, err := aibridged.New(ctx, pool, func(dialCtx context.Context) (aibridged.DRPCClient, error) {
|
||||
return coderAPI.CreateInMemoryAIBridgeServer(dialCtx)
|
||||
}, logger)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("start in-memory aibridge daemon: %w", err)
|
||||
}
|
||||
return srv, nil
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"database/sql"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
"tailscale.com/types/key"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/cryptorand"
|
||||
"github.com/coder/coder/v2/enterprise/audit"
|
||||
"github.com/coder/coder/v2/enterprise/audit/backends"
|
||||
@@ -23,6 +25,7 @@ import (
|
||||
"github.com/coder/coder/v2/enterprise/coderd/usage"
|
||||
"github.com/coder/coder/v2/enterprise/dbcrypt"
|
||||
"github.com/coder/coder/v2/enterprise/trialer"
|
||||
"github.com/coder/coder/v2/enterprise/x/aibridged"
|
||||
"github.com/coder/coder/v2/tailnet"
|
||||
"github.com/coder/quartz"
|
||||
"github.com/coder/serpent"
|
||||
@@ -143,6 +146,33 @@ func (r *RootCmd) Server(_ func()) *serpent.Command {
|
||||
}
|
||||
closers.Add(publisher)
|
||||
|
||||
experiments := agplcoderd.ReadExperiments(options.Logger, options.DeploymentValues.Experiments.Value())
|
||||
|
||||
var aibridgeDaemon *aibridged.Server
|
||||
// In-memory aibridge daemon.
|
||||
if options.DeploymentValues.AI.BridgeConfig.Enabled {
|
||||
if experiments.Enabled(codersdk.ExperimentAIBridge) {
|
||||
aibridgeDaemon, err = newAIBridgeDaemon(api)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("create aibridged: %w", err)
|
||||
}
|
||||
|
||||
api.RegisterInMemoryAIBridgedHTTPHandler(aibridgeDaemon)
|
||||
|
||||
// When running as an in-memory daemon, the HTTP handler is wired into the
|
||||
// coderd API and therefore is subject to its context. Calling Close() on
|
||||
// aibridged will NOT affect in-flight requests but those will be closed once
|
||||
// the API server is itself shutdown.
|
||||
closers.Add(aibridgeDaemon)
|
||||
} else {
|
||||
api.Logger.Warn(ctx, fmt.Sprintf("CODER_AIBRIDGE_ENABLED=true but experiment %q not enabled", codersdk.ExperimentAIBridge))
|
||||
}
|
||||
} else {
|
||||
if experiments.Enabled(codersdk.ExperimentAIBridge) {
|
||||
api.Logger.Warn(ctx, "aibridge experiment enabled but CODER_AIBRIDGE_ENABLED=false")
|
||||
}
|
||||
}
|
||||
|
||||
return api.AGPL, closers, nil
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user