Add 'Which AI agents developers are using' card to the AI Governance dashboard

Stacked on Add a reusable donut chart for the AI Governanc... (!256313 - merged).

What does this MR do and why?

What we're building and how

What. One card that answers "which AI agents are developers using?". The Show control picks the view:

  • All agents: one slice per agent, with every GitLab Duo session as one "GitLab Duo" slice.
  • DAP: GitLab Duo sessions only, one slice per flow (Chat, Code review, and so on).
  • Connected: external agents only, one slice per agent type (Claude Code, OpenCode).

A slice is the number of developers who used that agent or flow. The center is the number of developers across the whole view.

What "X developers" means. The number of distinct users who started at least one AI session in the group or project during the selected 7 or 30 days. A person counts once in the center even if they used several agents, and once in each slice they used, so the slices can add up to more than the center.

How it's calculated. One ClickHouse query over siphon_ai_governance_sessions, the replica of ai_governance_sessions. It takes the latest version of each session, drops deleted ones, keeps the sessions under the group or project path that started in the window, and returns each slice's sessions and distinct developers plus the exact totals in the same pass.

Out of scope. Flow labels use the dashboard's existing humanized names. Using the flows' own display names across the dashboard is a follow-up.

Data notes
ClickHouse query
SELECT
  if((source = 0 AND ifNull(agent_type, '') = ''), 'gitlab_duo',
     coalesce(nullIf(ifNull(agent_type, ''), ''), 'unknown')) AS name,
  count() AS sessions,
  uniqExact(user_id) AS developers,
  grouping(name) AS is_total
FROM (
  SELECT id, session_started_at,
    argMax(user_id, _siphon_replicated_at) AS user_id,
    argMax(source, _siphon_replicated_at) AS source,
    argMax(flow_type, _siphon_replicated_at) AS flow_type,
    argMax(agent_type, _siphon_replicated_at) AS agent_type,
    argMax(_siphon_deleted, _siphon_replicated_at) AS deleted
  FROM siphon_ai_governance_sessions
  WHERE startsWith(traversal_path, {traversal_path:String})
    AND session_started_at >= {from:DateTime64(6, 'UTC')}
    AND session_started_at < {to:DateTime64(6, 'UTC')}
  GROUP BY traversal_path, session_started_at, id
)
WHERE deleted = false
GROUP BY GROUPING SETS ((name), ())
ORDER BY is_total DESC, developers DESC, sessions DESC, name ASC
LIMIT {limit:UInt8}

DAP names slices by the version-less flow type and keeps only Duo sessions; Connected names them by agent type and keeps the rest. The primary key (traversal_path, session_started_at, id) prunes on the path prefix and the time window: with 2M sessions, a group's last 7 days read 88 of 980 granules (about 40 to 100 ms), a project's read 1.

Screenshots

All agents DAP Connected All agents, dark
all duo connected all-dark

How to set up and validate locally

  1. Enable ClickHouse for analytics and the flags ai_governance_dashboard and ai_governance_dashboard_charts for a group.
  2. Have sessions in siphon_ai_governance_sessions for that group from a few users across Duo flows and external agents.
  3. Open the group's AI Governance dashboard and switch the agent filter.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Rollout notes

  • The card reads ai_governance_sessions whenever ai_governance_dashboard_charts is on, while the tiles read that table only with ai_governance_sessions_api on. Enable the charts flag only where the sessions flag is on, so the card and the tiles count the same sessions.
  • Without ClickHouse the card shows its empty state, while the tiles fall back to PostgreSQL. The flag is wip and off by default; a ClickHouse-off message is a follow-up.
  • Developers can use several agents, so the slices can add up to more than the total. Percentages are computed against the distinct developer total.
Edited by Dheeraj Joshi

Merge request reports

Loading
Loading