feat(site/src/pages/DeploymentSettingsPage/LicensesSettingsPage): add per-license Products section with Coder Agents price gates - #28051
Conversation
… per-license Products section with Coder Agents price gates Each license card now always expands to a Products section: a Coder Workspaces box with active seat usage, and (on Premium licenses) a Coder Agents box driven by the agent_runtime_hours_* license claims and merged agent_runtime_hours entitlement. The Coder Agents box renders five states: no allocation (dashed purple upgrade CTA), unlimited (-1 sentinel), normal usage, allocation exceeded (red border, red 'Agent hours exceeded' status, chats stay Unlimited), and hard limit exceeded (red 'Hard limit exceeded' status, chats capped at 5, mirroring the backend's maxConcurrentRootAgents). Usage and overage indicators follow the AI Governance winning-license pattern via a generalized isLicenseApplicableForFeatureUsage helper. The header gains a Type column (Trial/Standard) and the left label now shows the feature set only (Premium/Enterprise).
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f00afbb9a8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Mirrors the backend's maxConcurrentRootAgents constant, which caps | ||
| // concurrent chats once the hard limit is reached. It is not exposed via | ||
| // the API, so keep this value in sync with the backend. | ||
| const maxConcurrentChatsOverHardLimit = 5; |
There was a problem hiding this comment.
Avoid claiming a five-chat cap before it is enforced
For Premium licenses with no allocation, or whose displayed usage reaches a hard limit, this constant tells admins that concurrent chats are capped at five. In the reviewed commit, however, decodeAgentRuntimeHours explicitly states that the concurrency-limited mode does not exist yet, and a repository-wide search finds no maxConcurrentRootAgents implementation. Either land the enforcement together with this UI or avoid displaying a fixed cap, otherwise the license page misrepresents the active price gate.
Useful? React with 👍 / 👎.
| : agentHoursAllocation !== undefined && | ||
| agentHoursAllocation > 0 && | ||
| agentHoursAllocation === agentRuntimeHoursFeature?.limit; |
There was a problem hiding this comment.
Use the merged usage period to identify the winning license
When two effective licenses have the same positive allocation, this equality marks both as the winner even though Entitlements.AddFeature selects a single license by feature comparison, with agent-runtime tests confirming that the newest issued-at license supplies the merged limits and usage period. A renewal can therefore make both cards display the same usage, and an older duplicate with a different hard threshold can incorrectly report Hard limit exceeded and the five-chat cap. Match the merged usage period or otherwise uniquely identify the selected license rather than comparing allocation alone.
Useful? React with 👍 / 👎.
| <button | ||
| type="button" | ||
| aria-label={`${label} information`} | ||
| className="m-0 inline-flex appearance-none border-0 bg-transparent p-0 text-content-secondary" | ||
| > |
There was a problem hiding this comment.
Exercise the new tooltip interactions in Storybook
These new tooltip buttons introduce keyboard and pointer interactions, but the added stories only inspect static metric text and never focus or hover either trigger to verify that its tooltip appears. Add play steps covering the real tooltip interaction and accessible content for both product cards, as required for frontend behavior changes.
AGENTS.md reference: site/AGENTS.md:L9-L10
Useful? React with 👍 / 👎.
| // The Users header field and the Coder Workspaces product card show | ||
| // the same seat usage. |
There was a problem hiding this comment.
Remove comments that narrate the following assertions
This comment merely paraphrases the immediately following getAllByText(...).toHaveLength(2) assertion, and the same story adds several similar comments immediately before checks for absent products and displayed concurrency. Remove these assertion narrations and retain comments only where they explain non-obvious behavior.
AGENTS.md reference: site/AGENTS.md:L15-L15
Useful? React with 👍 / 👎.
Each license card now always expands to a Products section: a Coder Workspaces box showing active seat usage, and, on Premium licenses, a Coder Agents box driven by the
agent_runtime_hours_*license claims and the mergedagent_runtime_hoursentitlement. The card header gains a Type column (Trial/Standard), and the left header label now shows the feature set only (Premium/Enterprise).The Coder Agents box renders five states: no allocation (dashed purple upgrade CTA), unlimited allocation (
-1sentinel), normal usage, allocation exceeded (red border and red "Agent hours exceeded" status; concurrent chats stay Unlimited), and hard limit exceeded (red "Hard limit exceeded" status; concurrent chats capped at 5, mirroring the backend'smaxConcurrentRootAgents, which is not exposed via the API). Usage and overage indicators only render on the license whose allocation matches the merged entitlement and which is currently effective, following the existing AI Governance winning-license pattern via a generalizedisLicenseApplicableForFeatureUsagehelper; AI Governance add-on behavior is unchanged.Stacked on #27985 (base branch
runtime-hours-entitlements); do not merge before it.Refs CODAGT-808. The Air-gapped license type is deferred until a license claim defines it.
Notes for review:
/deployment/groups(deployment-scoped) rather than the mock's default-org groups URL, since the default org is not guaranteed to be namedcoder.