Merge newest origin/master into token-meter-service

This commit is contained in:
Tianyi Cui
2026-07-17 22:49:54 +08:00
106 changed files with 1488 additions and 1353 deletions

View File

@@ -1,8 +1,8 @@
/**
* Conversation call configuration and freeze utilities. Model and sampling
* values, including provider routing, are request-header state that can affect cache reuse; request
* waterfalls replace them and the loop logs changes instead of allowing
* silent per-call drift.
* Conversation call configuration and freeze utilities. Provider routing,
* model, and sampling values are request-header state that can affect cache
* reuse; request waterfalls replace them and the loop logs changed snapshots
* instead of allowing silent per-call drift.
* @module dsh-llm/call-config
*/
@@ -22,7 +22,7 @@ export interface LlmCallConfig {
/**
* Field-wise equality over {@link LlmCallConfig} — the comparison a caller
* runs to decide whether a proposed configuration is a real change (worth a
* logged header delta) or the held one restated.
* logged header snapshot) or the held one restated.
* @param a - one configuration.
* @param b - the other.
* @returns whether every field (including the `stop` list, element-wise) matches.

View File

@@ -1,6 +1,6 @@
/**
* call-config unit tests: field-wise LlmCallConfig equality (the real-change
* detector behind logged header deltas) and the deepFreeze ownership helper
* detector behind logged changed headers) and the deepFreeze ownership helper
* the loop applies to every built request.
*/

View File

@@ -19,7 +19,7 @@ The estimator intentionally uses one fixed heuristic: four characters per token
`measure()` synchronizes once and returns one detached, deeply immutable snapshot. `totalTokens` is request-and-response pressure, while `surfaceTokens` is the surface-only heuristic total and equals the sum of `nodes[].tokens`. A `requestHeader` override affects pressure fields only; the surface fields still describe the current session. Every call clones the positional nodes, so measurement is O(surface).
The fold tracks request headers and deltas, step boundaries, surface appends and replacements, successful assistant messages, provider usage, and assistant-chunk provenance. Provider usage is reused only when the latest successful call's canonical request envelope matches the measured envelope and its total is no lower than that call's full heuristic anchor; a later success replaces the earlier anchor. Otherwise the complete current envelope and surface are estimated. Surface changes remain signed relative to a matching anchor, including negative deltas after shrinking replacements.
The fold tracks full request-header snapshots, step boundaries, surface appends and replacements, successful assistant messages, provider usage, and assistant-chunk provenance. Provider usage is reused only when the latest successful call's canonical request envelope matches the measured envelope and its total is no lower than that call's full heuristic anchor; a later success replaces the earlier anchor. Otherwise the complete current envelope and surface are estimated. Surface changes remain signed relative to a matching anchor, including negative deltas after shrinking replacements.
Usage accounting sums disjoint input, cache-read, cache-write, and output buckets; reasoning is not added again. Every successful call records an assistant anchor, including content-less calls. An explicit empty provenance list means a known empty provider stream, while absent legacy provenance conservatively treats the durable assistant output as provider output.

View File

@@ -9,7 +9,7 @@ import z from 'schemastery'
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 { applyHeaderDelta, canonicalHeader, headerEquals, isSurfaceEvent } from '@deepseek-ai/dsh-session'
import { canonicalHeader, headerEquals, isSurfaceEvent } from '@deepseek-ai/dsh-session'
import type {
TokenMeasurement,
TokenMeasurementBaseline,
@@ -220,12 +220,6 @@ export class TokenMeterService extends Service {
case 'request/header':
nextHeader = canonicalHeader(event.data.header)
break
case 'request/header-delta':
if (state.header === undefined) {
throw new Error(`token meter: request/header-delta at seq ${event.seq} has no preceding header`)
}
nextHeader = applyHeaderDelta(state.header, event.data)
break
case 'step/start':
if (state.stepStart !== undefined) {
throw new Error(

View File

@@ -375,10 +375,13 @@ describe('replay anchors and surface folds', () => {
}).baseline.kind).toBe('estimated')
})
it('folds valid header deltas into the effective envelope', () => {
const session = new Session(SessionId('header-delta'))
it('folds the latest full header snapshot into the effective envelope', () => {
const session = new Session(SessionId('header-snapshot'))
appendHeader(session, header('deepseek-v4-flash'))
session.append('request/header-delta', { config: { provider: 'mock', model: 'deepseek-v4-pro' } })
session.append('request/header', {
header: header('deepseek-v4-pro'),
reason: 'change',
})
const result = meter().measure(session)
expect(result.baseline.kind).toBe('estimated')
expect(result.logRevision).toBe(2)
@@ -401,7 +404,7 @@ describe('replay anchors and surface folds', () => {
expect(before.surfaceDeltaTokens).toBeGreaterThan(0)
expectSurfaceTotal(before)
const first = seeded.surface.nodes[0]!.seq
const first = seeded.surface.nodes[0]!
seeded.append('user/message', {
content: [{ type: 'text', text: 'replacement' }],
source: { kind: 'plugin', plugin: 'test' },
@@ -440,12 +443,6 @@ describe('malformed replay and listener lifecycle', () => {
expect(() => service.measure(session)).toThrow(pattern)
}
it('rejects a header delta before any snapshot transactionally', () => {
const session = new Session(SessionId('bad-delta'))
session.append('request/header-delta', { config: { provider: 'mock', model: 'deepseek-v4-flash' } })
expectRepeatedFailure(meter(), session, /no preceding header/)
})
it('rejects an assistant without its step boundary transactionally', () => {
const session = new Session(SessionId('bad-step'))
appendHeader(session, header('deepseek-v4-flash'))