Initial commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
export interface ContextUsageLike {
|
||||
contextTokens?: number | null
|
||||
contextWindow?: number | null
|
||||
contextRemainingPct?: number | null
|
||||
}
|
||||
|
||||
export interface ContextUsageMetrics {
|
||||
usedPct?: number
|
||||
remainingPct?: number
|
||||
usedTokens?: number
|
||||
windowTokens?: number
|
||||
}
|
||||
|
||||
function asFiniteNumber(value: number | null | undefined): number | undefined {
|
||||
if (typeof value !== 'number' || !Number.isFinite(value)) return undefined
|
||||
return value
|
||||
}
|
||||
|
||||
function clampPct(value: number): number {
|
||||
return Math.max(0, Math.min(Math.round(value), 100))
|
||||
}
|
||||
|
||||
export function getContextUsageMetrics(
|
||||
value: ContextUsageLike | null | undefined,
|
||||
): ContextUsageMetrics {
|
||||
const contextTokens = asFiniteNumber(value?.contextTokens)
|
||||
const contextWindow = asFiniteNumber(value?.contextWindow)
|
||||
const contextRemainingPct = asFiniteNumber(value?.contextRemainingPct)
|
||||
|
||||
const normalizedTokens = typeof contextTokens === 'number' ? Math.max(0, Math.round(contextTokens)) : undefined
|
||||
const normalizedWindow = typeof contextWindow === 'number' && contextWindow > 0
|
||||
? Math.max(1, Math.round(contextWindow))
|
||||
: undefined
|
||||
const normalizedRemainingPct = typeof contextRemainingPct === 'number'
|
||||
? clampPct(contextRemainingPct)
|
||||
: undefined
|
||||
|
||||
if (typeof normalizedTokens === 'number' && typeof normalizedWindow === 'number') {
|
||||
const usedTokens = Math.min(normalizedTokens, normalizedWindow)
|
||||
const usedPct = clampPct((usedTokens / normalizedWindow) * 100)
|
||||
return {
|
||||
usedPct,
|
||||
remainingPct: 100 - usedPct,
|
||||
usedTokens,
|
||||
windowTokens: normalizedWindow,
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof normalizedRemainingPct === 'number' && typeof normalizedWindow === 'number') {
|
||||
const usedPct = 100 - normalizedRemainingPct
|
||||
return {
|
||||
usedPct,
|
||||
remainingPct: normalizedRemainingPct,
|
||||
usedTokens: Math.round((usedPct / 100) * normalizedWindow),
|
||||
windowTokens: normalizedWindow,
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof normalizedWindow === 'number') {
|
||||
return {
|
||||
usedPct: 0,
|
||||
remainingPct: 100,
|
||||
usedTokens: 0,
|
||||
windowTokens: normalizedWindow,
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof normalizedRemainingPct === 'number') {
|
||||
// No usable window: the used/max ratio is undefined. Upstream reports an
|
||||
// unknown window as remaining_pct=0, so deriving usedPct here would render
|
||||
// a misleading 100% (or 0% at turn start). Surface remaining for any text
|
||||
// display but do not drive the ring — the ring hides without a usedPct.
|
||||
return { remainingPct: normalizedRemainingPct }
|
||||
}
|
||||
|
||||
if (typeof normalizedTokens === 'number') {
|
||||
return { usedTokens: normalizedTokens }
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
Reference in New Issue
Block a user