refactor(token-meter): merge measurement snapshots (round 1)

This commit is contained in:
Hypatia May
2026-07-16 14:38:24 +08:00
parent 19a56ec542
commit 6d96b3e4a8
14 changed files with 119 additions and 115 deletions

View File

@@ -14,7 +14,6 @@ import type {
TokenMeasurement,
TokenMeasurementBaseline,
TokenMeterConfig,
TokenSurfaceMeasurement,
TokenSurfaceNode,
} from './types.ts'
@@ -126,15 +125,19 @@ export class TokenMeterService extends Service {
}
/**
* Measure current request pressure through the session's durable tail.
* Measure current request pressure and surface through the durable tail.
*
* Provider usage is reused only when the latest successful call's canonical
* request envelope matches `requestHeader`; otherwise the complete envelope
* and surface are heuristically repriced.
*
* `requestHeader` affects request pressure only; surface fields always
* describe the current session surface. Every call clones those positional
* nodes, so measurement is O(surface).
*
* @param session - session to replay through its current durable tail.
* @param requestHeader - optional effective request envelope replacing the latest logged header.
* @returns a detached deeply immutable pressure measurement.
* @returns a detached deeply immutable pressure and surface measurement.
*/
measure(session: Session, requestHeader?: EpochHeader): TokenMeasurement {
const state = this._sync(session)
@@ -164,19 +167,7 @@ export class TokenMeterService extends Service {
baseline,
surfaceDeltaTokens,
totalTokens: Math.max(0, baseline.tokens + surfaceDeltaTokens),
}))
}
/**
* Price the current surface for retention and replacement decisions.
* @param session - session to replay through its current durable tail.
* @returns a detached deeply immutable positional surface measurement.
*/
measureSurface(session: Session): TokenSurfaceMeasurement {
const state = this._sync(session)
return deepFreeze(structuredClone({
logRevision: state.consumedEvents,
totalTokens: state.surfaceTokens,
surfaceTokens: state.surfaceTokens,
nodes: state.surface,
}))
}

View File

@@ -18,7 +18,7 @@ export type TokenMeasurementBaseline =
| { readonly kind: 'estimated'; readonly tokens: number }
| { readonly kind: 'usage'; readonly tokens: number; readonly usage: Readonly<TokenUsage> }
/** Detached immutable scalar pressure at one consumed session-log revision. */
/** Detached immutable request-pressure and surface snapshot at one consumed log revision. */
export interface TokenMeasurement {
/** Number of durable events consumed; equal to the next unread event seq. */
readonly logRevision: number
@@ -28,6 +28,10 @@ export interface TokenMeasurement {
readonly surfaceDeltaTokens: number
/** Non-negative current request-and-response pressure. */
readonly totalTokens: number
/** Total heuristic tokens across the current surface. */
readonly surfaceTokens: number
/** Current surface nodes in positional head-to-tail order. */
readonly nodes: readonly TokenSurfaceNode[]
}
/** One token-priced node in the current ordered session surface. */
@@ -37,13 +41,3 @@ export interface TokenSurfaceNode {
/** Heuristic tokens for the exact message projected by this node. */
readonly tokens: number
}
/** Detached immutable priced surface at one consumed session-log revision. */
export interface TokenSurfaceMeasurement {
/** Number of durable events consumed; equal to the next unread event seq. */
readonly logRevision: number
/** Total heuristic tokens across the current surface. */
readonly totalTokens: number
/** Current surface nodes in positional head-to-tail order. */
readonly nodes: readonly TokenSurfaceNode[]
}