mirror of
https://github.com/coder/coder.git
synced 2026-10-28 02:42:54 +08:00
feat: remove legacy chat provider tables (#25416)
This commit is contained in:
+66
-48
@@ -350,13 +350,8 @@ func (p *Server) resolveAdvisorModelOverride(
|
||||
return fallbackModel, fallbackCallConfig
|
||||
}
|
||||
|
||||
// GetEnabledChatModelConfigByID checks the model config and referenced
|
||||
// provider enabled state, so it returns sql.ErrNoRows the moment an
|
||||
// admin disables either one. Using the cached ModelConfigByID here
|
||||
// would keep resolving an override whose provider was just disabled,
|
||||
// and an available fallback key would let ModelFromConfig succeed,
|
||||
// silently routing advisor prompts to a provider the admin expects to
|
||||
// be off.
|
||||
// Re-read the override instead of using the cache so disabled models
|
||||
// or providers stop routing advisor prompts immediately.
|
||||
overrideConfig, err := p.db.GetEnabledChatModelConfigByID(
|
||||
ctx,
|
||||
advisorCfg.ModelConfigID,
|
||||
@@ -7102,9 +7097,8 @@ func (p *Server) runChat(
|
||||
// Fire title generation asynchronously so it doesn't block the
|
||||
// chat response. It uses a detached context so it can finish
|
||||
// even after the chat processing context is canceled.
|
||||
// Snapshot model, provider keys, logger, and ctx before launch; all four get
|
||||
// reassigned below (model = cuModel, providerKeys = computerUseProviderKeys,
|
||||
// logger = logger.With(...), ctx = runCtx) and the goroutine captures by reference.
|
||||
// Snapshot values captured by the goroutine because model, providerKeys,
|
||||
// logger, and ctx are reassigned below.
|
||||
titleModel := model
|
||||
titleProviderKeys := providerKeys
|
||||
titleLogger := logger
|
||||
@@ -8502,13 +8496,17 @@ func (p *Server) resolveChatModel(
|
||||
}
|
||||
|
||||
func (p *Server) aiProviderConfig(ctx context.Context, provider database.AIProvider) (chatprovider.ConfiguredProvider, error) {
|
||||
if !provider.Enabled {
|
||||
return chatprovider.ConfiguredProvider{}, xerrors.Errorf("AI provider %s is disabled", provider.ID)
|
||||
}
|
||||
keys, err := p.db.GetAIProviderKeysByProviderID(ctx, provider.ID)
|
||||
if err != nil {
|
||||
return chatprovider.ConfiguredProvider{}, xerrors.Errorf("get AI provider keys: %w", err)
|
||||
}
|
||||
return p.aiProviderConfigFromKeys(provider, keys)
|
||||
}
|
||||
|
||||
func (p *Server) aiProviderConfigFromKeys(provider database.AIProvider, keys []database.AIProviderKey) (chatprovider.ConfiguredProvider, error) {
|
||||
if !provider.Enabled {
|
||||
return chatprovider.ConfiguredProvider{}, xerrors.Errorf("AI provider %s is disabled", provider.ID)
|
||||
}
|
||||
apiKey := ""
|
||||
// GetAIProviderKeysByProviderID orders keys oldest first. chatd consumes
|
||||
// one provider-scoped key because runtime provider config has one API key slot.
|
||||
@@ -8529,6 +8527,48 @@ func (p *Server) aiProviderConfig(ctx context.Context, provider database.AIProvi
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Server) aiProviderConfigs(ctx context.Context, providers []database.AIProvider) ([]chatprovider.ConfiguredProvider, error) {
|
||||
if len(providers) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
providerIDs := make([]uuid.UUID, 0, len(providers))
|
||||
for _, provider := range providers {
|
||||
providerIDs = append(providerIDs, provider.ID)
|
||||
}
|
||||
keys, err := p.db.GetAIProviderKeysByProviderIDs(ctx, providerIDs)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get AI provider keys: %w", err)
|
||||
}
|
||||
keysByProviderID := make(map[uuid.UUID][]database.AIProviderKey, len(providers))
|
||||
for _, key := range keys {
|
||||
keysByProviderID[key.ProviderID] = append(keysByProviderID[key.ProviderID], key)
|
||||
}
|
||||
configuredProviders := make([]chatprovider.ConfiguredProvider, 0, len(providers))
|
||||
for _, provider := range providers {
|
||||
configuredProvider, err := p.aiProviderConfigFromKeys(provider, keysByProviderID[provider.ID])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configuredProviders = append(configuredProviders, configuredProvider)
|
||||
}
|
||||
return configuredProviders, nil
|
||||
}
|
||||
|
||||
func ensureUniqueConfiguredProviderTypes(providers []chatprovider.ConfiguredProvider) error {
|
||||
seen := make(map[string]uuid.UUID, len(providers))
|
||||
for _, provider := range providers {
|
||||
normalizedProvider := chatprovider.NormalizeProvider(provider.Provider)
|
||||
if normalizedProvider == "" {
|
||||
continue
|
||||
}
|
||||
if existingProviderID, ok := seen[normalizedProvider]; ok && existingProviderID != provider.ProviderID {
|
||||
return xerrors.Errorf("multiple enabled AI providers use provider type %q; select an AI provider by ID", normalizedProvider)
|
||||
}
|
||||
seen[normalizedProvider] = provider.ProviderID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Server) resolveUserProviderAPIKeysForProvider(
|
||||
ctx context.Context,
|
||||
ownerID uuid.UUID,
|
||||
@@ -8559,12 +8599,6 @@ func (p *Server) resolveUserProviderAPIKeysForProvider(
|
||||
[]chatprovider.ConfiguredProvider{configuredProvider},
|
||||
userKeys,
|
||||
)
|
||||
enabledProviders := map[string]struct{}{}
|
||||
normalizedProvider := chatprovider.NormalizeProvider(configuredProvider.Provider)
|
||||
if normalizedProvider != "" {
|
||||
enabledProviders[normalizedProvider] = struct{}{}
|
||||
}
|
||||
chatprovider.PruneDisabledProviderKeys(&keys, enabledProviders)
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
@@ -8598,9 +8632,6 @@ func (p *Server) resolveUserProviderAPIKeys(
|
||||
ownerID uuid.UUID,
|
||||
selectedAIProviderID uuid.UUID,
|
||||
) (chatprovider.ProviderAPIKeys, error) {
|
||||
var configuredProviders []chatprovider.ConfiguredProvider
|
||||
userKeys := []chatprovider.UserProviderKey{}
|
||||
|
||||
if selectedAIProviderID != uuid.Nil {
|
||||
provider, err := p.db.GetAIProviderByID(ctx, selectedAIProviderID)
|
||||
if err != nil {
|
||||
@@ -8608,48 +8639,35 @@ func (p *Server) resolveUserProviderAPIKeys(
|
||||
}
|
||||
return p.resolveUserProviderAPIKeysForProvider(ctx, ownerID, provider)
|
||||
}
|
||||
|
||||
providers, err := p.configCache.EnabledProviders(ctx)
|
||||
if err != nil {
|
||||
return chatprovider.ProviderAPIKeys{}, xerrors.Errorf(
|
||||
"get enabled chat providers: %w",
|
||||
"get enabled AI providers: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
configuredProviders = make(
|
||||
[]chatprovider.ConfiguredProvider, 0, len(providers),
|
||||
)
|
||||
for _, provider := range providers {
|
||||
configuredProviders = append(
|
||||
configuredProviders, chatprovider.ConfiguredProvider{
|
||||
ProviderID: provider.ID,
|
||||
Provider: provider.Provider,
|
||||
APIKey: provider.APIKey,
|
||||
BaseURL: provider.BaseUrl,
|
||||
CentralAPIKeyEnabled: provider.CentralApiKeyEnabled,
|
||||
AllowUserAPIKey: provider.AllowUserApiKey,
|
||||
AllowCentralAPIKeyFallback: provider.AllowCentralApiKeyFallback,
|
||||
},
|
||||
)
|
||||
configuredProviders, err := p.aiProviderConfigs(ctx, providers)
|
||||
if err != nil {
|
||||
return chatprovider.ProviderAPIKeys{}, err
|
||||
}
|
||||
allowAnyUserAPIKey := false
|
||||
for _, provider := range configuredProviders {
|
||||
if provider.AllowUserAPIKey {
|
||||
allowAnyUserAPIKey = true
|
||||
break
|
||||
}
|
||||
if err := ensureUniqueConfiguredProviderTypes(configuredProviders); err != nil {
|
||||
return chatprovider.ProviderAPIKeys{}, err
|
||||
}
|
||||
if allowAnyUserAPIKey {
|
||||
userKeyRows, err := p.db.GetUserChatProviderKeys(ctx, ownerID)
|
||||
|
||||
userKeys := []chatprovider.UserProviderKey{}
|
||||
if p.allowBYOK {
|
||||
userKeyRows, err := p.db.GetUserAIProviderKeysByUserID(ctx, ownerID)
|
||||
if err != nil {
|
||||
return chatprovider.ProviderAPIKeys{}, xerrors.Errorf(
|
||||
"get user chat provider keys: %w",
|
||||
"get user AI provider keys: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
userKeys = make([]chatprovider.UserProviderKey, 0, len(userKeyRows))
|
||||
for _, userKey := range userKeyRows {
|
||||
userKeys = append(userKeys, chatprovider.UserProviderKey{
|
||||
ChatProviderID: userKey.ChatProviderID,
|
||||
ChatProviderID: userKey.AIProviderID,
|
||||
APIKey: userKey.APIKey,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user