show subagent token metrics
This commit is contained in:
@@ -173,19 +173,30 @@
|
||||
}
|
||||
|
||||
.summary,
|
||||
.time {
|
||||
.metrics {
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
font-size: 11px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.time {
|
||||
.metrics {
|
||||
display: grid;
|
||||
grid-template-rows: 18px 16px;
|
||||
flex: none;
|
||||
margin-top: 16px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.metricToken {
|
||||
grid-row: 1;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.metricDuration {
|
||||
grid-row: 2;
|
||||
}
|
||||
|
||||
.children {
|
||||
position: relative;
|
||||
margin-left: 18px;
|
||||
|
||||
@@ -12,6 +12,7 @@ import type { PropsLocale, PropsRuntime, TranslateNS } from '@deepseek-ai/dsh-cl
|
||||
import { NS } from './locales.ts'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-conversation/client'
|
||||
import type {} from '@deepseek-ai/dsh-subagent/client'
|
||||
import type {} from '@deepseek-ai/dsh-token-meter/client'
|
||||
import css from './SubagentCatalogAction.module.css'
|
||||
|
||||
type CatalogEntry = SubagentCatalogSnapshot['entries'][number]
|
||||
@@ -59,6 +60,26 @@ function treeItems(root: HTMLDivElement | null): HTMLElement[] {
|
||||
: Array.from(root.querySelectorAll<HTMLElement>('[role="treeitem"]:not([aria-disabled="true"])'))
|
||||
}
|
||||
|
||||
/** Compact token count shared in shape with the conversation stats strip. */
|
||||
function formatTokens(value: number): string {
|
||||
const scaled = (next: number): string => next >= 100
|
||||
? String(Math.round(next))
|
||||
: String(Math.round(next * 10) / 10)
|
||||
if (value < 1_000) return String(value)
|
||||
if (value < 1_000_000) return `${scaled(value / 1_000)}K`
|
||||
return `${scaled(value / 1_000_000)}M`
|
||||
}
|
||||
|
||||
/** Sum the four disjoint durable provider-usage buckets. */
|
||||
function tokenTotal(
|
||||
usage: SessionProjectionMap['tokenUsage'] | undefined,
|
||||
): number | undefined {
|
||||
return usage === undefined
|
||||
? undefined
|
||||
: usage.uncachedInputTokens + usage.outputTokens
|
||||
+ usage.cacheReadTokens + usage.cacheWriteTokens
|
||||
}
|
||||
|
||||
/** Exact whole-second active-turn duration for one catalog row. */
|
||||
function activityDuration(
|
||||
summary: SessionSummary | undefined,
|
||||
@@ -222,14 +243,21 @@ function CatalogRows({
|
||||
const secondary = [summary?.title, mode, activity]
|
||||
.filter(value => value !== undefined)
|
||||
.join(' · ')
|
||||
const totalTokens = tokenTotal(summary?.projectionValues?.tokenUsage)
|
||||
const durationMs = activityDuration(
|
||||
summary,
|
||||
entry.activity,
|
||||
now,
|
||||
)
|
||||
const duration = durationMs === undefined
|
||||
const tokenMetric = totalTokens === undefined
|
||||
? undefined
|
||||
: `${formatTokens(totalTokens)} tok`
|
||||
const durationMetric = durationMs === undefined
|
||||
? undefined
|
||||
: formatDuration(durationMs, t)
|
||||
const metrics = [tokenMetric, durationMetric]
|
||||
.filter(value => value !== undefined)
|
||||
.join(' · ')
|
||||
|
||||
const open = (): void => {
|
||||
openChild({ parentSessionId, childSessionId: entry.id, mode: entry.mode })
|
||||
@@ -261,9 +289,7 @@ function CatalogRows({
|
||||
role="treeitem"
|
||||
tabIndex={0}
|
||||
aria-level={level}
|
||||
aria-label={[label, secondary, duration]
|
||||
.filter(value => value !== undefined)
|
||||
.join(' ')}
|
||||
aria-label={[label, secondary, metrics].filter(value => value !== '').join(' ')}
|
||||
{...knownLeaf ? {} : { 'aria-expanded': isExpanded }}
|
||||
className={css.row}
|
||||
onClick={open}
|
||||
@@ -288,7 +314,12 @@ function CatalogRows({
|
||||
<span className={css.label}>{label}</span>
|
||||
<span className={css.summary}>{secondary}</span>
|
||||
</span>
|
||||
{duration !== undefined && <span className={css.time}>{duration}</span>}
|
||||
{metrics !== '' && (
|
||||
<span className={css.metrics}>
|
||||
{tokenMetric !== undefined && <span className={css.metricToken}>{tokenMetric}</span>}
|
||||
{durationMetric !== undefined && <span className={css.metricDuration}>{durationMetric}</span>}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{isExpanded && !knownLeaf && (
|
||||
|
||||
Reference in New Issue
Block a user