User setting fallback mechanism for no-context request | Model Selection
Context
For Model selection we need to be able to route request when no namespace is given. For instance, when a developer is working in a new repo that is not yet an GitLab project or when they use the various AI capabilities of the GitLab CLI.
Task
Once the user is capable of choosing a default duo enabled seat assignment with namespace from the settings, when a duo request is made and we are checking namespaces and if no namespace is passed 3 scenarios can occur:
- The user only has one duo seats assignment:
- Use this seat assignment's namespace to route the request to the right model
- The user has duo seats assignment in multiple namespaces, and has set a default duo enabled assigmnent.
- Use the seat assignment's namespace chosen by the user to route the request to the right model
- The user has duo seat assignments in multiple namespaces, and has not set a default duo enabled assignment.
- Raise an exception prompting the user to set an default duo enabled assignment in his user preferences.
Implementation Proposal
In ::Ai::ModelSelection::NamespaceFeatureSetting change .find_or_initialize_by_feature(namespace, feature) to accept the namespace argument to be optional as well as an user argument.
The new interface should look like this:
def self.find_or_initialize_by_feature(feature, namespace: nil, user: nil)
# Use namespace if present
# fallback to user default if no namespace
# raised if neither namespace or user is passed
end
Adapt how .find_or_initialize_by_feature is used in the codebase accordinly.
How to retrieve the namespace from the user seat assignment?
See !196400 (merged) for context.
The UserPreference model now house 2 method that will be helpful for you:
-
UserPreference#default_duo_add_on_assignment: This method retrieves the seat assignment currently chosen by the user. -
UserPreference#eligible_duo_add_on_assignments: This method retrieves all the seat assignment elligable to be defaults for model selection.
With those two method you could build something like this in Ai::ModelSelection::NamespaceFeatureSetting.
def self.resolve_namespace_with_user(user)
user_preference = user.user_preference
default_assigned_seat = user_preference.default_duo_add_on_assignment # check if a seat is assigned in user_preference
return default_assigned_seat.add_on_purchase.namespace if default_assigned_seat.present?
eligible_duo_seats = user_preference.eligible_duo_add_on_assignments
return eligible_duo_seats.first.add_on_purchase.namespace if eligible_duo_seats.count == 1 # return the only eligible seat namespace if there is only one
raise ArgumentError, # return error if seats !== 1
'Unable to resolve namespace with given user. Set a default seat assignment the user preferences.'
end