[go: up one dir, main page]

Skip to content

Expose Project.aiCatalogItems field

What does this MR do and why?

Adds a Project.aiCatalogItems GraphQL field to return back:

  • Enabled AI Catalog items of the project
  • Disabled AI Catalog items of the project
  • AI Catalog items available to the project (that are public)

#577040

How to set up and validate locally

Enable the global_ai_catalog flag.

(Optional). Path your local to allow any project to create AI Catalog items.

diff --git a/ee/app/models/ee/project.rb b/ee/app/models/ee/project.rb
index dc8c5541fcea..c6ac444489ec 100644
--- a/ee/app/models/ee/project.rb
+++ b/ee/app/models/ee/project.rb
@@ -622,6 +622,7 @@ def suggested_reviewers_available?
       end

       def ai_catalog_available?
+        return true
         duo_features_enabled && ::Gitlab::Llm::StageCheck.available?(self, :ai_catalog)
       end
       strong_memoize_attr :ai_catalog_available?

Visit http://gdk.test:3000/explore/ai-catalog/agents/ and create some agents for a project https://docs.gitlab.com/user/duo_agent_platform/agents/#create-an-agent.

Add some of the agents to the project https://docs.gitlab.com/user/duo_agent_platform/agents/#enable-an-agent.

Create some public agents for another project. Also create some private agents for that project.

Add some of those public agents to the project too.

Now test out the GraphQL field. Visit http://gdk.test:3000/-/graphql-explorer, and try these queries:

No filtering arguments:

{
  project(fullPath: "<Project full path>") {
    aiCatalogItems {
      nodes {
        id
        itemType
        name
        description
      }
    }
  }
}

Only items that have been enabled, that are agents, and contain a particular string in their name or description:

{
  project(fullPath: "<Project full path>") {
    aiCatalogItems(enabled: true, search: "pirate", itemTypes: [AGENT]) {
      nodes {
        id
        itemType
        name
        description
      }
    }
  }
}

All agents available (ones created by the project, and public ones from other projects)

{
  project(fullPath: "<Project full path>") {
    aiCatalogItems(allAvailable: true, itemTypes: [AGENT]) {
      nodes {
        id
        itemType
        name
        description
      }
    }
  }
}

Remove an agent from the project (Go Automate > Agents for the project, and remove one).

You should have that agent returned by querying for enabled: false.

{
  project(fullPath: "<Project full path>") {
    aiCatalogItems(enabled: false) {
      nodes {
        id
        itemType
        name
        description
      }
    }
  }
}

Queries

Create some data:

-- Create 5,000 agents for gitlab-org/gitlab

exec INSERT INTO "ai_catalog_items" 
  ("organization_id", "project_id", "created_at", "updated_at", "item_type", "description", "name")
SELECT 
  1, 
  278964, 
  NOW(), 
  NOW(), 
  1, 
  'agent description', 
  'agent name'
FROM generate_series(1, 5000);

-- Create 5,000 flows for gitlab-org/gitlab

exec INSERT INTO "ai_catalog_items" 
  ("organization_id", "project_id", "created_at", "updated_at", "item_type", "description", "name")
SELECT 
  1, 
  278964, 
  NOW(), 
  NOW(), 
  2, 
  'flow description', 
  'flow name'
FROM generate_series(1, 5000);

-- Create 5,000 public agents for gitlab-org/gitlab-foss

exec INSERT INTO "ai_catalog_items" 
  ("organization_id", "project_id", "created_at", "updated_at", "item_type", "description", "name", "public")
SELECT 
  1, 
  13083,
  NOW(), 
  NOW(), 
  1, 
  'other agent description', 
  'other agent name',
  TRUE
FROM generate_series(1, 5000);

-- Enable 1,000 of the agents for gitlab-org/gitlab

exec INSERT INTO "ai_catalog_item_consumers" 
  ("ai_catalog_item_id", "project_id", "created_at", "updated_at", "enabled")
SELECT 
  id,
  278964,
  NOW(), 
  NOW(), 
  TRUE
FROM ai_catalog_items
  WHERE project_id = 278964
  LIMIT 1000;

Default SQL produced by GraphQL endpoint through finder:

Ai::Catalog::ProjectItemsFinder.new(user, project).execute

SQL for gitlab-org/gitlab

SELECT
    "ai_catalog_items".*
FROM
    "ai_catalog_items"
WHERE
    "ai_catalog_items"."deleted_at" IS NULL
    AND "ai_catalog_items"."project_id" = 278964
ORDER BY
    "ai_catalog_items"."id" DESC;

Explain https://console.postgres.ai/gitlab/gitlab-production-main/sessions/44766/commands/137422.

Example SQL produced by GraphQL endpoint through finder with all arguments provided:

Ai::Catalog::ProjectItemsFinder.new(user, project, params: { item_types: ['agent'], enabled: true, search: 'agent', all_available: true }).execute

SQL for gitlab-org/gitlab

SELECT
    "ai_catalog_items".*
FROM
    "ai_catalog_items"
WHERE
    "ai_catalog_items"."deleted_at" IS NULL
    AND ("ai_catalog_items"."project_id" = 278964
        OR "ai_catalog_items"."organization_id" = 1
        AND "ai_catalog_items"."public" = TRUE)
    AND "ai_catalog_items"."item_type" = 1
    AND "ai_catalog_items"."id" IN (
        SELECT
            "ai_catalog_item_consumers"."ai_catalog_item_id"
        FROM
            "ai_catalog_item_consumers"
        WHERE
            "ai_catalog_item_consumers"."project_id" = 278964
            AND "ai_catalog_item_consumers"."enabled" = TRUE)
    AND ("ai_catalog_items"."name" ILIKE '%agent%'
        OR "ai_catalog_items"."description" ILIKE '%agent%')
ORDER BY
    "ai_catalog_items"."id" DESC

Explain https://console.postgres.ai/gitlab/gitlab-production-main/sessions/44766/commands/137424

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #577040

Edited by Luke Duncalfe

Merge request reports

Loading