feat(client): show the stats legend shares at 0.1% precision
fmtShare rounded to whole percents with a <1% crumb floor, which bunched everything under 1% together and hid real differences in the two donut legends. Shares now carry one decimal (73.8%, 26.1%), the crumb floor tightens to <0.1%, empty slices read 0.0%, and the 100% cap is unchanged.
This commit is contained in:
1 parent
07aae76261
commit
914c54da3d
4 files changed
+32
-29
No files matched your search
@@ -39,16 +39,16 @@ export function fmtTime(t: number): string {
|
||||
|
||||
/**
|
||||
* Share of a whole as a compact leading percentage for the slice rows:
|
||||
* '—' when nothing totals, '0%' for empty slices, '<1%' for non-zero crumbs
|
||||
* a rounded-down integer would erase. Shares cap at 100% (parallel tool time
|
||||
* can over-run the wall it belongs to).
|
||||
* '—' when nothing totals, '0.0%' for empty slices, '<0.1%' for non-zero
|
||||
* crumbs a 0.1%-precision figure would erase. One decimal everywhere; shares
|
||||
* cap at 100% (parallel tool time can over-run the wall it belongs to).
|
||||
*/
|
||||
export function fmtShare(part: number, total: number): string {
|
||||
if (!Number.isFinite(part) || !Number.isFinite(total) || total <= 0) return '—'
|
||||
if (part <= 0) return '0%'
|
||||
if (part <= 0) return '0.0%'
|
||||
const pct = Math.min(1, part / total) * 100
|
||||
if (pct < 1) return '<1%'
|
||||
return `${Math.round(pct)}%`
|
||||
if (pct < 0.1) return '<0.1%'
|
||||
return `${pct.toFixed(1)}%`
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,10 +47,10 @@ describe('StatsTiming', () => {
|
||||
assert.ok(text(m.container).includes('Timing Stats'))
|
||||
assert.equal(query(m.container, '.lc-donut-center b').textContent, '10m 0s')
|
||||
assert.equal(query(m.container, '.lc-donut-center span').textContent, 'Active Time')
|
||||
assert.deepEqual(rowOf(m.container, 0), { pct: '40%', label: 'Model calls', count: '4m 0s · 10 calls', dim: false })
|
||||
assert.deepEqual(rowOf(m.container, 0), { pct: '40.0%', label: 'Model calls', count: '4m 0s · 10 calls', dim: false })
|
||||
// The tools row keeps the true 5m sum even though the ring clamps it.
|
||||
assert.deepEqual(rowOf(m.container, 1), { pct: '50%', label: 'Tool runs', count: '5m 0s · 25 runs', dim: false })
|
||||
assert.deepEqual(rowOf(m.container, 2), { pct: '10%', label: 'Overhead', count: '1m 0s', dim: false })
|
||||
assert.deepEqual(rowOf(m.container, 1), { pct: '50.0%', label: 'Tool runs', count: '5m 0s · 25 runs', dim: false })
|
||||
assert.deepEqual(rowOf(m.container, 2), { pct: '10.0%', label: 'Overhead', count: '1m 0s', dim: false })
|
||||
// Three ring segments painted (lm + tools + overhead); exactly three rows.
|
||||
assert.equal(queryAll(m.container, '.lc-donut circle').length, 3)
|
||||
assert.equal(queryAll(m.container, '.lc-sl-row').length, 3)
|
||||
@@ -60,7 +60,7 @@ describe('StatsTiming', () => {
|
||||
test('the zh locale formats durations and counts in Chinese units', async () => {
|
||||
const m = await mount(h(StatsTimingZh, { timing: TIMING, locale: 'zh' }))
|
||||
assert.equal(query(m.container, '.lc-donut-center b').textContent, '10分0秒')
|
||||
assert.deepEqual(rowOf(m.container, 0), { pct: '40%', label: '模型调用', count: '4分0秒 · 10次', dim: false })
|
||||
assert.deepEqual(rowOf(m.container, 0), { pct: '40.0%', label: '模型调用', count: '4分0秒 · 10次', dim: false })
|
||||
await m.unmount()
|
||||
})
|
||||
|
||||
@@ -68,12 +68,12 @@ describe('StatsTiming', () => {
|
||||
// 9 parallel 22s calls inside a 100s wall: tools sum 200s > wall.
|
||||
const timing: TimingTotals = { wallMs: 100_000, lmMs: 60_000, calls: 2, toolsMs: 200_000, toolCalls: 9, tools: { bash: { calls: 9, ms: 200_000 } } }
|
||||
const m = await mount(h(StatsTiming, { timing, locale: 'en' }))
|
||||
assert.deepEqual(rowOf(m.container, 1), { pct: '100%', label: 'Tool runs', count: '3m 20s · 9 runs', dim: false })
|
||||
assert.deepEqual(rowOf(m.container, 1), { pct: '100.0%', label: 'Tool runs', count: '3m 20s · 9 runs', dim: false })
|
||||
// The ring clamps tools into the 40s post-model window; the zero
|
||||
// overhead segment is skipped: 2 circles, not 3.
|
||||
assert.equal(queryAll(m.container, '.lc-donut circle').length, 2)
|
||||
// The zero overhead row dims whole.
|
||||
assert.deepEqual(rowOf(m.container, 2), { pct: '0%', label: 'Overhead', count: '—', dim: true })
|
||||
assert.deepEqual(rowOf(m.container, 2), { pct: '0.0%', label: 'Overhead', count: '—', dim: true })
|
||||
// The hover link: the zero-overhead row tints itself but leaves the ring
|
||||
// at rest (no painted arc to light); a painted row dims the ring.
|
||||
const rows = queryAll(m.container, '.lc-sl-row')
|
||||
|
||||
@@ -33,9 +33,9 @@ describe('StatsTokens', () => {
|
||||
assert.equal(query(m.container, '.lc-donut-center span').textContent, 'Cache Hit')
|
||||
// Zero buckets stay hidden: the always-zero DeepSeek cache write drops out.
|
||||
assert.equal(queryAll(m.container, '.lc-sl-row').length, 3)
|
||||
assert.deepEqual(rowOf(m.container, 0), { pct: '67%', label: 'Cached Input', count: '300' })
|
||||
assert.deepEqual(rowOf(m.container, 1), { pct: '22%', label: 'Uncached Input', count: '100' })
|
||||
assert.deepEqual(rowOf(m.container, 2), { pct: '11%', label: 'Output', count: '50 · incl. reasoning' })
|
||||
assert.deepEqual(rowOf(m.container, 0), { pct: '66.7%', label: 'Cached Input', count: '300' })
|
||||
assert.deepEqual(rowOf(m.container, 1), { pct: '22.2%', label: 'Uncached Input', count: '100' })
|
||||
assert.deepEqual(rowOf(m.container, 2), { pct: '11.1%', label: 'Output', count: '50 · incl. reasoning' })
|
||||
await m.unmount()
|
||||
})
|
||||
|
||||
@@ -58,10 +58,10 @@ describe('StatsTokens', () => {
|
||||
// Hit = 300 / (100 + 300 + 50) = 66.66%; rows normalize over billed 500.
|
||||
assert.equal(query(m.container, '.lc-donut-center b').textContent, '66.66%')
|
||||
assert.equal(queryAll(m.container, '.lc-sl-row').length, 4)
|
||||
assert.deepEqual(rowOf(m.container, 0), { pct: '60%', label: 'Cached Input', count: '300' })
|
||||
assert.deepEqual(rowOf(m.container, 1), { pct: '10%', label: 'Cache Write', count: '50' })
|
||||
assert.deepEqual(rowOf(m.container, 2), { pct: '20%', label: 'Uncached Input', count: '100' })
|
||||
assert.deepEqual(rowOf(m.container, 3), { pct: '10%', label: 'Output', count: '50 · incl. reasoning' })
|
||||
assert.deepEqual(rowOf(m.container, 0), { pct: '60.0%', label: 'Cached Input', count: '300' })
|
||||
assert.deepEqual(rowOf(m.container, 1), { pct: '10.0%', label: 'Cache Write', count: '50' })
|
||||
assert.deepEqual(rowOf(m.container, 2), { pct: '20.0%', label: 'Uncached Input', count: '100' })
|
||||
assert.deepEqual(rowOf(m.container, 3), { pct: '10.0%', label: 'Output', count: '50 · incl. reasoning' })
|
||||
await m.unmount()
|
||||
})
|
||||
|
||||
|
||||
+13
-10
@@ -77,18 +77,21 @@ describe('fmtShare', () => {
|
||||
assert.equal(fmtShare(5, Infinity), '—')
|
||||
})
|
||||
|
||||
test('empty slices are 0%; crumbs below a point round up to <1%', () => {
|
||||
assert.equal(fmtShare(0, 100), '0%')
|
||||
assert.equal(fmtShare(-1, 100), '0%')
|
||||
assert.equal(fmtShare(0.5, 100), '<1%')
|
||||
assert.equal(fmtShare(1, 300), '<1%')
|
||||
test('empty slices are 0.0%; crumbs below 0.1% degrade to <0.1%', () => {
|
||||
assert.equal(fmtShare(0, 100), '0.0%')
|
||||
assert.equal(fmtShare(-1, 100), '0.0%')
|
||||
assert.equal(fmtShare(1, 2000), '<0.1%')
|
||||
assert.equal(fmtShare(1, 1000), '0.1%')
|
||||
assert.equal(fmtShare(0.5, 100), '0.5%')
|
||||
assert.equal(fmtShare(1, 300), '0.3%')
|
||||
})
|
||||
|
||||
test('shares round to whole percents and cap at 100', () => {
|
||||
assert.equal(fmtShare(844, 1000), '84%')
|
||||
assert.equal(fmtShare(996, 1000), '100%')
|
||||
assert.equal(fmtShare(3000, 1000), '100%')
|
||||
assert.equal(fmtShare(1, 3), '33%')
|
||||
test('shares carry one decimal and cap at 100', () => {
|
||||
assert.equal(fmtShare(844, 1000), '84.4%')
|
||||
assert.equal(fmtShare(738.4, 1000), '73.8%')
|
||||
assert.equal(fmtShare(996, 1000), '99.6%')
|
||||
assert.equal(fmtShare(3000, 1000), '100.0%')
|
||||
assert.equal(fmtShare(1, 3), '33.3%')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in new issue
Block a user