review: address ds-review-bot findings on session-stats
- stateVersion starts at 1: the package is new, no persisted rows predate it - pendingCalls pairs by own key so a provider callId naming a prototype property cannot fold toolMs to NaN on an unmatched crash-recovery result - StatsLine folds the window fallback only when no sessionStats value is served, and gates the token group on actual token activity instead of steps, so failed-only sessions drop the zero-token group - correct the crash-step counting semantics in the README and Agent Note: recovery closes interrupted steps with a synthetic step/end on reload - reword the window-scoped alternative as a plain rejected option and name isTokenDelta's home beside the StreamChunk type
This commit is contained in:
@@ -140,8 +140,12 @@ export const sessionStatsProjectionDefinition: ProjectionDefinition<'sessionStat
|
||||
case 'tool/call':
|
||||
return { ...state, pendingCalls: { ...state.pendingCalls, [event.data.callId]: event.time } }
|
||||
case 'tool/result': {
|
||||
// Own-key check: callId is provider-minted (model/tool JSON boundary),
|
||||
// so a prototype property name ('constructor', 'toString') on a result
|
||||
// with no recorded call must read as unmatched, not as an inherited
|
||||
// function that would poison toolMs with NaN.
|
||||
const callId = event.data.message.source.callId
|
||||
const dispatched = state.pendingCalls[callId]
|
||||
const dispatched = Object.hasOwn(state.pendingCalls, callId) ? state.pendingCalls[callId] : undefined
|
||||
if (dispatched === undefined) return state
|
||||
const pendingCalls = Object.fromEntries(
|
||||
Object.entries(state.pendingCalls).filter(([id]) => id !== callId),
|
||||
@@ -175,5 +179,5 @@ export const sessionStatsProjectionDefinition: ProjectionDefinition<'sessionStat
|
||||
decodeMs: state.decodeMs,
|
||||
decodeTokens: state.decodeTokens,
|
||||
}),
|
||||
stateVersion: 2,
|
||||
stateVersion: 1,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user