Wire Inbox Session Design to Duo Experimental Setting
Problem
The redesigned session inbox is gated only by the duo_panel_session_inbox WIP flag.
getNamespaceIndexComponent in
ee/app/assets/javascripts/ai/duo_agents_platform/router/utils.js reads
window.gon?.features?.duoPanelSessionInbox and picks either AgentSessionInbox or
userAgentsPlatformIndex. A chatops percentage rollout is the only lever, so nobody
outside the actors we name in #production can turn it on.
The epic (&23179 (closed)) ships to Customer Zero
first and then promotes to Experiment or Beta. Promotion means the Duo "Experiment and
beta features" setting decides who sees it — NamespaceSetting#experiment_features_enabled
on .com, Gitlab::CurrentSettings.instance_level_ai_beta_features_enabled? on
self-managed. The inbox reads neither today.
Gitlab::Llm::StageCheck.available? will not do it for us: it consults those settings
only when the feature's maturity is :experimental or :beta, and duo_workflow,
duo_agent_platform and foundational_flows are all maturity: :ga in
ee/lib/gitlab/llm/utils/ai_features_catalogue.rb. Ai::DuoAgentPlatform::AccessPolicy
already passes with the setting off.
Proposal
Inject the setting at the same place the flag is already checked —
getNamespaceIndexComponent — so one condition still decides which component the
sessions route renders, and the setting-off path falls back to userAgentsPlatformIndex
exactly as the flag-off path does. Both off-paths matter: a self-managed instance with
the instance setting off does not get the redesign, flag or no flag.
The check is user-level, not container-level. The panel's container is whatever page you
happen to be on, and gating on it would make the inbox appear on one project and vanish
on the next while the session list itself is the same user-scoped list either way. On
.com, use User#any_group_with_ai_available? in
ee/app/models/concerns/ai/user_authorizable.rb —
member_namespaces.namespace_settings_with_ai_features_enabled.with_ai_supported_plan.any?,
where that scope is experiment_features_enabled: true. It is cached per user, so this
does not add a per-request query. Note it also carries a with_ai_supported_plan clause,
which is a tighter answer than the setting alone. On self-managed, read
Gitlab::CurrentSettings.instance_level_ai_beta_features_enabled?.
The value reaches the frontend the way the panel gets the rest of its server state, not
through gon. DuoChatPanel::ChatComponent already builds the panel's data hash (see
billing_attributes, is_saas) and has user in scope, so compute it inline there,
consistent with the neighbouring attributes. Other frontends already take this setting as
a data attribute — vulnerabilities_helper, ee/app/helpers/ee/groups_helper.rb and
groups/security_features_helper all pass experiment_features_enabled stringified.
init_duo_panel.js parseBooleans it and threads it into createRouter, which already
carries per-panel config into the route table.
One implementation note: getNamespaceIndexComponent(namespace) takes only the namespace
today and reaches for window.gon itself, so threading a second input changes its
signature and both call sites (ai_panel_router.js and router/index.js). Reading a
second gon value instead would keep the signature but leave the panel's server state
split across two transports.
Acceptance criteria
- The redesigned inbox requires both the
duo_panel_session_inboxflag and the Duo experiment/beta setting. - The check lands in
getNamespaceIndexComponent, so the sessions route still has one branch and every off-path rendersuserAgentsPlatformIndex. - .com resolves the setting per user via
User#any_group_with_ai_available?; self-managed reads the instance setting. - A self-managed instance with the instance setting off never renders the redesign.
- The setting reaches the frontend through the panel component's data attributes, not
gon. - Specs cover flag on/off crossed with setting on/off, on .com and self-managed.
- Docs and version history describe the feature as Experiment.
- The rollout checklist in #616496 (closed) says the flag no longer decides visibility on its own.
References
- Epic: &23179 (closed)
- Inbox behind the flag: #616493 (closed)
- Flag rollout: #616496 (closed)
- UX: #612102 (closed)
- MRs: !250917 (merged) (flag, merged), !251149 (merged) (inbox), !251191 (merged) (tab counts)
ee/app/assets/javascripts/ai/duo_agents_platform/router/utils.js,ee/app/assets/javascripts/ai/init_duo_panel.js,ee/app/components/duo_chat_panel/chat_component.rb,ee/app/models/concerns/ai/user_authorizable.rb,ee/lib/gitlab/llm/stage_check.rb,ee/lib/gitlab/llm/utils/ai_features_catalogue.rb