getUserChatProviderAvailability returns the enabled chat providers and models the user can access. Deployment-level configuration is read as chatd, while user key lookups still use the caller's authorization context.
( ctx context.Context, userID uuid.UUID, )
| 774 | // the user can access. Deployment-level configuration is read as chatd, while |
| 775 | // user key lookups still use the caller's authorization context. |
| 776 | func (api *API) getUserChatProviderAvailability( |
| 777 | ctx context.Context, |
| 778 | userID uuid.UUID, |
| 779 | ) (userChatModelAvailability, error) { |
| 780 | //nolint:gocritic // Chatd context is required to read enabled chat config. |
| 781 | chatdCtx := dbauthz.AsChatd(ctx) |
| 782 | enabledProviders, err := api.Database.GetAIProviders(chatdCtx, database.GetAIProvidersParams{}) |
| 783 | if err != nil { |
| 784 | return userChatModelAvailability{}, err |
| 785 | } |
| 786 | enabledModels, err := api.Database.GetEnabledChatModelConfigs(chatdCtx) |
| 787 | if err != nil { |
| 788 | return userChatModelAvailability{}, err |
| 789 | } |
| 790 | |
| 791 | configuredProviders, err := api.configuredProvidersFromAIProviders(chatdCtx, enabledProviders) |
| 792 | if err != nil { |
| 793 | return userChatModelAvailability{}, err |
| 794 | } |
| 795 | availability := userChatModelAvailability{ |
| 796 | configuredProviders: configuredProviders, |
| 797 | configuredModels: make([]chatprovider.ConfiguredModel, 0, len(enabledModels)), |
| 798 | enabledModels: enabledModels, |
| 799 | enabledProviderNames: make(map[string]struct{}, len(enabledProviders)), |
| 800 | enabledProviderIDs: make(map[uuid.UUID]struct{}, len(enabledProviders)), |
| 801 | providerStatusByID: make(map[uuid.UUID]chatprovider.ProviderAvailability, len(enabledProviders)), |
| 802 | } |
| 803 | for _, configuredProvider := range configuredProviders { |
| 804 | normalizedProvider := chatprovider.NormalizeProvider(configuredProvider.Provider) |
| 805 | if normalizedProvider != "" { |
| 806 | availability.enabledProviderNames[normalizedProvider] = struct{}{} |
| 807 | } |
| 808 | if configuredProvider.ProviderID != uuid.Nil { |
| 809 | availability.enabledProviderIDs[configuredProvider.ProviderID] = struct{}{} |
| 810 | } |
| 811 | } |
| 812 | userKeys := []chatprovider.UserProviderKey{} |
| 813 | if api.DeploymentValues.AI.BridgeConfig.AllowBYOK.Value() { |
| 814 | userKeyRows, err := api.Database.GetUserAIProviderKeysByUserID(ctx, userID) |
| 815 | if err != nil { |
| 816 | return userChatModelAvailability{}, err |
| 817 | } |
| 818 | userKeys = make([]chatprovider.UserProviderKey, 0, len(userKeyRows)) |
| 819 | for _, userKey := range userKeyRows { |
| 820 | userKeys = append(userKeys, chatprovider.UserProviderKey{ |
| 821 | ChatProviderID: userKey.AIProviderID, |
| 822 | APIKey: userKey.APIKey, |
| 823 | }) |
| 824 | } |
| 825 | } |
| 826 | |
| 827 | fallbackKeys := ChatProviderAPIKeysFromDeploymentValues(api.DeploymentValues) |
| 828 | mergeProviderStatus := func( |
| 829 | statuses map[string]chatprovider.ProviderAvailability, |
| 830 | normalizedProvider string, |
| 831 | status chatprovider.ProviderAvailability, |
| 832 | ) { |
| 833 | current, ok := statuses[normalizedProvider] |
no test coverage detected