feat(site): show total agent hours consumption on the licenses page - #27953
Conversation
65c87f5 to
eebd138
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eebd138c60
ℹ️ 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".
ibetitsmike
left a comment
There was a problem hiding this comment.
Mux reviewed this pull request on behalf of Mike.
Requesting fixes for two threshold-state defects and a Storybook assertion gap. These are separate from the existing over-allocation tooltip thread.
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4fbce07c98
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 819e488caf
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5f30d5237
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d2b32e3846
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a3cdafa918
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6e73e2dc97
ℹ️ 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".
|
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
ibetitsmike
left a comment
There was a problem hiding this comment.
Mux submitted this review on Mike's behalf.
0580b5a to
e4f4f1a
Compare
ibetitsmike
left a comment
There was a problem hiding this comment.
Mux reviewed this pull request on Mike's behalf.
Reviewed exact head e4f4f1ae996d9ec03a72e8259491a13c05cc7d0f against the PR merge-base with runtime-hours-entitlements.
Code review
Standards: PASS. The component reuses existing primitives and fixtures, keeps derived state in render, and has comprehensive Storybook interaction coverage.
Spec: one P3 finding. Unlimited, disabled, missing-data, invalid-limit, usage-period, soft-limit, allocation, hard-cap, and fractional-hour states otherwise match the PR description.
P3: Avoid floating-point underflow in displayed percentages
site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/TotalAgentHoursCard.tsx:155
formatPercent floors value * 10, but the input is already a floating-point ratio. For example, (29 / 100) * 100 evaluates to 28.999999999999996, so the tooltip displays 28.9% instead of the exact 29% configured by the integer claims. Similar cases affect 57%, 58%, and other ratios.
Please calculate the tenths percentage from the integer inputs, or otherwise compensate for representation error before flooring. Add a story that uses a ratio such as 29 of 100 and asserts 29%.
Frontend review
FE1 PASS
FE2 PASS
FE3 PASS
FE4 PASS
FE5 PASS
FE6 PASS
FE7 PASS
FE8 PASS
FE9 PASS
FE10 PASS
The two older unresolved GitHub threads are outdated and their reported behaviors are fixed at this head.
2468616 to
24e060b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e717937cfb
ℹ️ 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".
An enabled agent_runtime_hours feature with the limit omitted means the license grants unlimited runtime hours (allocation claim -1). The card previously rendered the invalid-limits error for that shape; it now shows a full neutral bar with "Limit: Unlimited" and the tooltip without threshold copy, mirroring SeatUsageBarCard's unlimited state. The invalid-limits error is kept for negative limits, which can only come from a decoding bug.
The allocation-reached tooltip now reports the floored actual usage percentage (1,200 of 1,000 hours shows 120%) instead of always claiming 100%. The soft-limit percentage is floored rather than rounded so a 999/1,000-hour soft limit displays as 99% instead of crossing the allocation boundary. Missing usage data no longer counts as reaching a zero soft limit, and story tooltip assertions query the role=tooltip node so they fail when the popover does not open.
A full green bar with no thresholds read as 100% usage. Unlimited allocations now fill the track with purple diagonal stripes so the full-width bar reads as an unmetered allocation instead of usage approaching a limit.
The unlimited allocation bar keeps its diagonal stripes but switches from purple back to the green highlight, and the right half of the bar fades out into the track so the pattern reads as an open-ended allocation rather than a full meter.
When a license carries a hard limit, the track scales to the enforcement range: a solid red line marks the hard cap at the right edge and a dotted yellow line marks the allocation, whose limit label follows the marker. If the allocation sits close enough to the hard cap for the labels to collide, the hard cap label moves above the bar. Usage at or beyond the hard cap fills the track with red diagonal stripes and the tooltip names the cap. Threshold percentages now render with one floored decimal place (999/1,000 hours shows 99.9% instead of 99%), still never crossing a boundary the underlying hours have not reached.
…w total agent hours with one decimal Derive the Total agent hours card's usage from the entitlement's new actual_ms field, floored to tenths of an hour with integer math so the displayed number and the reached states flip at the same instant as the backend's whole-hour thresholds. Usage renders with exactly one decimal (e.g. 435.8, 1,000.0); the limit and hard cap labels stay whole because the claims are whole hours.
The fill is now colored by position instead of switching as a whole: green until the soft limit, yellow from the soft limit to the allocation, and red from the allocation to the hard cap. Each threshold carries a marker line extending past the track: dotted yellow for the soft limit, red for the allocation, and a double-width primary-color line for the hard cap. Reaching the hard cap shows a destructive pill above the bar stating that chat concurrency is enforced. New stories cover usage between the soft limit and the allocation and between the allocation and the hard cap.
… agent hours labels inside the card Replace the emdash fallback for missing usage data with N/A, and move the limit label above the bar when the allocation marker sits within the first 15% of a hard-cap scaled track, where the centered label would spill outside the card and over the Used label.
…ect agent hours reached states Turn the whole fill red when a metered allocation without a hard cap is reached: the track ends at the allocation, so there is no position past the limit where a red segment could render, and the previous gating on a hard cap left the bar green or yellow in the reached state. Also drop the concurrency-enforcement claim from the hard-cap pill because no backend path enforces the hard limit yet.
Add MockAgentRuntimeHoursFeature to testHelpers/entities and spread it in every TotalAgentHoursCard story instead of re-declaring the server Feature shape per story, so entitlement defaults and the paired actual/actual_ms fields stay defined in one place.
… reuse the runtime hours fixture in the view story Spread MockAgentRuntimeHoursFeature in the TotalAgentHoursUsage view story instead of rebuilding the entity inline, and drop the story comment that restated the story name and its ordering assertion.
Below the md breakpoint the centered limit label collides with the right-aligned hard cap label at interior marker positions, so it moves above the bar instead, left-aligned in the row shared with the hard-cap pill. Also drop the fixture comment that restated the MockAgentRuntimeHoursFeature values.
… the bar red at a coincident hard cap The backend accepts a hard cap equal to the allocation, which places the shared threshold at the track's right edge where no red segment can render past the limit. Key the full-red reached fill on the limit boundary sitting at the track edge instead of on the absence of a hard cap, so the coincident case reads as reached like the no-cap case.
Renders the usage period dates above the bar, matching ManagedAgentsConsumption, so admins can tell which license period the shown consumption covers. A missing or unparsable period omits the dates row; the MissingUsagePeriod story pins that fallback and the shared fixture gains a usage_period. Also trims the narrated comments in the card and its stories down to the non-obvious invariants, per review.
… the hard cap badge and use reached wording The shared Badge applies text-nowrap, so the full-sentence hard cap badge overflowed narrow cards; this instance wraps instead. The badge shows at usage equal to the hard cap (the boundary where the concurrency cap re-engages), so it now reads "limit reached" rather than "exceeded", which is false at equality. Also replaces the en dash in the usage period label with a hyphen, which broke CI at lint/emdash.
ca71301 to
1e010df
Compare
Adds a "Total agent hours" consumption panel to the Licenses page, surfacing the
agent_runtime_hoursentitlement introduced by the #27983 / #27984 / #27985 stack.The new
TotalAgentHoursCardrenders full width directly above the Agent Workspace Builds panel. It shows a usage bar with Used/Limit labels and an info tooltip next to the title. The bar color and tooltip copy track the same thresholds the backend uses for license warnings: green below the soft limit, orange once usage reaches the soft limit, and red once usage reaches the purchased allocation (values at or beyond the threshold count as reached, matchingappendAgentRuntimeHoursWarning). When a soft limit exists, the tooltip states the actual soft-limit percentage computed fromsoft_limit / limit. The panel is hidden entirely when the feature is disabled, which is how the backend reports a zero-hour allocation.The usage period dates from
Feature.usage_periodrender above the bar (start left, end right), matching the Agent Workspace Builds panel, so admins can tell which license period the consumption covers. The backend always attaches a period to an enabled feature; a missing or unparsable one just omits the dates row. The CODAGT-855 link to the per-user usage view is deferred: that view (F3, CODAGT-861) and the API it needs (F2, CODAGT-857) are not built yet, so there is no route to target. The link lands with F3.An enabled feature with
limitomitted is the unlimited allocation (license claim-1, coder/license#49): the card shows a full neutral bar with "Limit: Unlimited" and the tooltip without threshold copy, mirroringSeatUsageBarCard's unlimited state. The invalid-limits error is kept for negative limits, which can only come from a decoding bug.Storybook stories cover the green/orange/red states, the capped over-allocation bar, missing usage data, the missing usage period, the hidden state, the unlimited state, the invalid-limit error state, and each tooltip message via play interactions. The page view story verifies the panel renders above Agent Workspace Builds.
Usage renders with exactly one decimal (e.g.
435.8,1,000.0), derived from #27985'sactual_msfield and floored to tenths with integer math. The same floored value drives the reached states, so the displayed number and the bar color flip at the same instant; a fraction past the allocation now trips the red state (1,000.1 >= 1,000), pinned by theReachedAllocationByFractionstory. The limit and hard cap labels stay whole because the license claims are whole hours.Stacked on #27985.
closes CODAGT-855.