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)
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