feat(token-meter): project durable token usage

This commit is contained in:
Hypatia May
2026-07-29 14:35:24 +08:00
parent 741b760557
commit e37cb23336
9 changed files with 383 additions and 1 deletions

View File

@@ -10,12 +10,15 @@ import { BlockAssembler, deepFreeze } from '@deepseek-ai/dsh-llm'
import type { ContentBlock, Message, TokenUsage } from '@deepseek-ai/dsh-llm'
import type { EpochHeader, Session, SessionEvent, SurfaceEvent } from '@deepseek-ai/dsh-session'
import { canonicalHeader, headerEquals, isSurfaceEvent } from '@deepseek-ai/dsh-session'
// Type-only: resolves the optional projection registry Context seam.
import type {} from '@deepseek-ai/dsh-session-projection'
import type {
TokenMeasurement,
TokenMeasurementBaseline,
TokenMeterConfig,
TokenSurfaceNode,
} from './types.ts'
import { tokenUsageProjectionDefinition } from './usage-projection.ts'
export type * from './types.ts'
@@ -90,6 +93,12 @@ export class TokenMeterService extends Service {
super(ctx, 'tokenMeter')
validateConfigKeys(config)
// Projection registration is an optional child: headless and TUI
// compositions without the generic registry keep the meter's old shape.
ctx.inject(['sessionProjections'], (projectionCtx) => {
projectionCtx.sessionProjections.register(tokenUsageProjectionDefinition)
})
// Readers catch up independently, while eager observation bounds ordinary
// read latency without creating state for sessions no consumer has read.
ctx.on('session/event', (session) => {