mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
Closes [AIGOV-455](https://linear.app/codercom/issue/AIGOV-455/extend-drpc-with-buildproviders). ## Why The AI Gateway (`aibridged`) is being split into a standalone process that must not touch the database. `coderd` stays the source of truth and seeds the `ai_providers` / `ai_provider_keys` tables from the environment. This PR adds a DRPC call so the gateway fetches provider config from `coderd` instead of reading the DB, for both the embedded and standalone daemons. ## What - **Proto:** new `ProviderConfigurator` service with a unary `GetAIProviders` RPC, plus `AIProvider` / `AIProviderBedrock` messages. `CurrentMinor` bumped to 1 (additive). - **Server (`coderd/aibridgedserver`):** `GetAIProviders` runs a read-only `InTx` under `LockIDAIProvidersEnvSeed` so it never returns a mid-seed snapshot, reads providers (incl. disabled) plus keys for enabled ones, and maps to proto under `dbauthz.AsAIBridged`. Unmappable rows are skipped and logged; plaintext keys and Bedrock secrets are never logged. - **Client:** `DRPCProviderConfiguratorClient` wired into the client union, `dialer.go`, and `CreateInMemoryAIBridgeServer`. - **cli:** `BuildProvidersFromProto` maps the response through the existing DB-neutral `buildProvider`. A shared `poolRPCReloader` does the fetch/build/replace for both daemons: the embedded daemon reloads on every `ai_providers` change and fails startup if it cannot subscribe; the standalone gateway drives the same reloader once at startup, retrying until success and staying interruptible. - **Dead code removed:** `BuildProvidersFromConfig`, `ProvidersFromConfig`, `AIProviderFromConfig`, and the DB-read `BuildProviders` path.
37 lines
707 B
Go
37 lines
707 B
Go
package aibridged
|
|
|
|
import (
|
|
"context"
|
|
|
|
"storj.io/drpc"
|
|
|
|
"github.com/coder/coder/v2/coderd/aibridged/proto"
|
|
)
|
|
|
|
type Dialer func(ctx context.Context) (DRPCClient, error)
|
|
|
|
type ClientFunc func() (DRPCClient, error)
|
|
|
|
// DRPCClient is the union of various service interfaces the client must support.
|
|
type DRPCClient interface {
|
|
proto.DRPCRecorderClient
|
|
proto.DRPCMCPConfiguratorClient
|
|
proto.DRPCAuthorizerClient
|
|
proto.DRPCProviderConfiguratorClient
|
|
}
|
|
|
|
var _ DRPCClient = &Client{}
|
|
|
|
type Client struct {
|
|
proto.DRPCRecorderClient
|
|
proto.DRPCMCPConfiguratorClient
|
|
proto.DRPCAuthorizerClient
|
|
proto.DRPCProviderConfiguratorClient
|
|
|
|
Conn drpc.Conn
|
|
}
|
|
|
|
func (c *Client) DRPCConn() drpc.Conn {
|
|
return c.Conn
|
|
}
|