Sign in or sign up before continuing. Don't have an account yet? Register now to get started.
Register now
BE: Filter projects for agent/flow association to Premium+ projects (with Duo Features enabled if possible)
## Problem [As discussed in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/572017), there is currently no way to filter the list of projects available for agent/flow association by the required eligibility criteria: - Project belongs to a **Premium+ licensing tier** namespace - Project has **Duo Features enabled** (`ProjectSetting.duo_features_enabled`) - On SaaS, **Free tier projects** are also eligible if they have an active `gitlab_credits` add-on purchase - Project has opted in to **Experimental/Beta features** (differs between SaaS and Self-Managed) — applicable to Custom Flows only, as Agents are now GA ## Implementation Plan Add a new `duoLicensedFeature` filter to the projects GraphQL query that returns only projects eligible for a specific GitLab Duo AI feature. The filter should handle two deployment types: - **Self-Managed**: Check if the requested feature is available through the instance license. If licensed, return all projects with Duo features enabled. - **SaaS (GitLab.com)**: Check the namespace's subscription plan (Premium+) or active `gitlab_credits` add-on to determine eligibility, then return matching projects with Duo features enabled. **Important note**: When `duoLicensedFeature` is used, the system internally enforces that only projects where the current user has **maintainer+ role** are returned. This ensures that the GraphQL field does not expose licensing information about projects the user is not a maintainer+ of. `duoLicensedFeature` is an **ENUM** type (`DuoLicensedFeature`) with three possible values: * `AGENTIC_CHAT` * `AI_CATALOG` * `AI_FEATURES` The filter should be marked as **Experimental** and target GitLab **18.11**. ## Example Usage ```graphql query fetch_projects { projects( duoLicensedFeature: AI_CATALOG ) { nodes { fullPath name } count } } ``` The above query returns all projects for which the `ai_catalog` feature is available. Internally, the system filters projects based on the following criteria: 1. **Duo platform availability**: GitLab Duo is available at the top-level namespace (SaaS) or instance level (Self-Managed). 2. **Project-level setting**: The `duo_features_enabled` setting is enabled for the project. 3. **Tier eligibility**: The top-level namespace or instance has a matching subscription tier for the requested AI feature. Tier requirements vary by feature: * `AI_CATALOG` and `AGENTIC_CHAT`: Available for **Premium+** tiers. * `AI_FEATURES`: Available for **Ultimate** tier only. * **Free tier** projects are also eligible if they have an active add-on credits purchase (`gitlab_credits`), as Duo AI Platform (DAP) has been available for Free tier with add-on credits since **18.10**. **NOTE:** Changes on the scope `Namespace.with_ai_supported_plan` is behind the feature flag `filter_projects_by_duo_licensed_feature`, here is the FF roll out issue - https://gitlab.com/gitlab-org/gitlab/-/work_items/595308 <details> <summary>Previous description</summary> ## Currently [As discussed in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/572017), there is no way to filter the list of projects available for agent/flow association by the criteria required: - Project has Premium+ licensing tier - Project has Duo Features enabled (`ProjectSetting.duo_features_enabled`) - Project has opted-in to Experimenta/Beta features ([different for SaaS vs Self-Managed](https://gitlab.com/gitlab-org/gitlab/-/blob/de32881a9c452e36de9eedad1e61825c1ffc15bb/ee/lib/gitlab/llm/stage_check.rb#L77-94)) Ideally, we would filter on both dimensions so that only projects eligible for agent/flow attachment are shown. ## For this iteration Expose the existing `by_plans` filter from `ProjectsFinder` in GraphQL. **Important note**: As we don't want to allow the GraphQL field to expose this information for projects the user is not a maintainer of, `ProjectsFinder` should only allow scoping by the new arguments if the set of projects being returned are ones that the user is maintainer+ of - this is because we don't want to expose this information about projects the user is not maintainer+ of. Therefore, the [`min_access_level` arg](https://gitlab.com/gitlab-org/gitlab/-/blob/cfd39e86e064e3c43a9bd9e3c797f594c57324eb/app/graphql/resolvers/projects_resolver.rb#L111) must be either `[Gitlab::Access::MAINTAINER, Gitlab::Access::OWNER]` in order for the new GraphQL argument to be used, otherwise GraphQL should return an error. The backend engineer could also do the corresponding ~frontend issue also if they feel comfortable https://gitlab.com/gitlab-org/gitlab/-/issues/572017. The frontend changes would need to be deployed after the backend change to avoid multi-version compatibility problems. Or if the backend engineer is not comfortable with the frontend change, update https://gitlab.com/gitlab-org/gitlab/-/issues/572017 with the new GraphQL arguments added on the ~backend. </details>
issue