fix(token-meter): close projected usage review gaps
This commit is contained in:
@@ -20,8 +20,8 @@ export interface TokenUsageProjection {
|
||||
/**
|
||||
* Approximate context occupancy for a status display.
|
||||
*
|
||||
* The two fields are deliberately NOT one atomic request observation:
|
||||
* `pressureTokens` is the newest provider-reported prompt size in the log,
|
||||
* The two fields, when present, are deliberately NOT one atomic request
|
||||
* observation: `pressureTokens` is the newest provider-reported prompt size,
|
||||
* `contextWindow` the newest recorded route capacity. Switching models can
|
||||
* therefore pair a fresh capacity with the previous route's pressure until the
|
||||
* next request reports usage. This is an intentional trade — the value is a
|
||||
@@ -33,9 +33,9 @@ export interface ContextPressureProjection {
|
||||
/**
|
||||
* Provider-reported prompt size of the most recent request: uncached input
|
||||
* plus cache reads and writes. Response output is excluded, so this does not
|
||||
* grow as the current turn streams.
|
||||
* grow as the current turn streams. Absent until a provider reports usage.
|
||||
*/
|
||||
pressureTokens: number
|
||||
pressureTokens?: number
|
||||
/** Newest recorded route capacity; absent when no adapter advertised one. */
|
||||
contextWindow?: number
|
||||
}
|
||||
|
||||
@@ -56,10 +56,10 @@ const projectionSchema = z.object({
|
||||
cacheWriteTokens: z.number().int().nonnegative(),
|
||||
}).strict()
|
||||
|
||||
// Cast for the optional capacity: under exactOptionalPropertyTypes zod infers
|
||||
// `number | undefined` where the interface declares an absent-or-number field.
|
||||
// Cast for the optional values: under exactOptionalPropertyTypes zod infers
|
||||
// `number | undefined` where the interface declares absent-or-number fields.
|
||||
const pressureSchema = z.object({
|
||||
pressureTokens: z.number().int().nonnegative(),
|
||||
pressureTokens: z.number().int().nonnegative().optional(),
|
||||
contextWindow: z.number().int().positive().optional(),
|
||||
}).strict() as unknown as z.ZodType<ContextPressureProjection>
|
||||
|
||||
@@ -128,12 +128,14 @@ export const contextPressureProjectionDefinition:
|
||||
ProjectionDefinition<'contextPressure', ContextPressureProjection> = {
|
||||
key: 'contextPressure',
|
||||
schema: pressureSchema,
|
||||
init: () => ({ pressureTokens: 0 }),
|
||||
init: () => ({}),
|
||||
apply: (state, event) => {
|
||||
if (event.type === 'request/context') {
|
||||
return event.data.contextWindow === state.contextWindow
|
||||
? state
|
||||
: { ...state, contextWindow: event.data.contextWindow }
|
||||
const contextWindow = event.data.contextWindow
|
||||
if (contextWindow === state.contextWindow) return state
|
||||
if (contextWindow !== undefined) return { ...state, contextWindow }
|
||||
const { contextWindow: _removed, ...withoutContextWindow } = state
|
||||
return withoutContextWindow
|
||||
}
|
||||
const usage = event.type === 'assistant/chunk' && event.data.chunk.type === 'usage'
|
||||
? event.data.chunk.usage
|
||||
@@ -147,5 +149,5 @@ ProjectionDefinition<'contextPressure', ContextPressureProjection> = {
|
||||
: { ...state, pressureTokens }
|
||||
},
|
||||
view: state => state,
|
||||
stateVersion: 1,
|
||||
stateVersion: 2,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user