|
|
|
@@ -147,7 +147,7 @@ describe('TokenMeterService pricing', () => {
|
|
|
|
|
|
|
|
|
|
it('returns a detached deeply immutable empty measurement', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('empty'))
|
|
|
|
|
const session = Session.create(SessionId('empty'))
|
|
|
|
|
const result = service.measure(session)
|
|
|
|
|
expect(result).toEqual({
|
|
|
|
|
logRevision: 0,
|
|
|
|
@@ -168,7 +168,7 @@ describe('TokenMeterService pricing', () => {
|
|
|
|
|
|
|
|
|
|
it('keeps an earlier unified snapshot detached from later replay', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('detached'))
|
|
|
|
|
const session = Session.create(SessionId('detached'))
|
|
|
|
|
session.append('user/message', createUserMessage({
|
|
|
|
|
content: [{ type: 'text', text: 'first' }],
|
|
|
|
|
source: { kind: 'user' },
|
|
|
|
@@ -200,7 +200,7 @@ describe('TokenMeterService pricing', () => {
|
|
|
|
|
|
|
|
|
|
it('prices header, tools, and surface when no reusable usage exists', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('heuristic'))
|
|
|
|
|
const session = Session.create(SessionId('heuristic'))
|
|
|
|
|
session.append('user/message', createUserMessage({
|
|
|
|
|
content: [{ type: 'text', text: 'question' }],
|
|
|
|
|
source: { kind: 'user' },
|
|
|
|
@@ -218,7 +218,7 @@ describe('TokenMeterService pricing', () => {
|
|
|
|
|
|
|
|
|
|
it('keeps request-header overrides out of the returned surface', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('override-surface'))
|
|
|
|
|
const session = Session.create(SessionId('override-surface'))
|
|
|
|
|
session.append('user/message', createUserMessage({
|
|
|
|
|
content: [{ type: 'text', text: 'question' }],
|
|
|
|
|
source: { kind: 'user' },
|
|
|
|
@@ -246,7 +246,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
|
|
|
|
|
it('uses disjoint provider usage and signed durable-output rewrites', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('usage'))
|
|
|
|
|
const session = Session.create(SessionId('usage'))
|
|
|
|
|
session.append('user/message', createUserMessage({
|
|
|
|
|
content: [{ type: 'text', text: 'before' }],
|
|
|
|
|
source: { kind: 'user' },
|
|
|
|
@@ -267,7 +267,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
|
|
|
|
|
it('selects a heuristic anchor when provider usage would undercut its scale', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('low-usage-anchor'))
|
|
|
|
|
const session = Session.create(SessionId('low-usage-anchor'))
|
|
|
|
|
const system = 'system context'
|
|
|
|
|
const requestHeader = header('deepseek-v4-flash', { system })
|
|
|
|
|
appendSuccessfulCall(session, requestHeader, {
|
|
|
|
@@ -297,7 +297,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
|
|
|
|
|
it('uses an estimated anchor when provider usage is absent', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('missing-usage'))
|
|
|
|
|
const session = Session.create(SessionId('missing-usage'))
|
|
|
|
|
appendSuccessfulCall(session, header('deepseek-v4-flash', { system: 's' }), {
|
|
|
|
|
providerText: 'provider',
|
|
|
|
|
durableText: 'rewritten',
|
|
|
|
@@ -314,8 +314,8 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('distinguishes explicit empty provenance from absent legacy provenance', () => {
|
|
|
|
|
const explicit = new Session(SessionId('explicit-empty'))
|
|
|
|
|
const legacy = new Session(SessionId('legacy-absent'))
|
|
|
|
|
const explicit = Session.create(SessionId('explicit-empty'))
|
|
|
|
|
const legacy = Session.create(SessionId('legacy-absent'))
|
|
|
|
|
appendSuccessfulCall(explicit, header('deepseek-v4-flash'), {
|
|
|
|
|
durableText: 'listener injected text',
|
|
|
|
|
providerText: '',
|
|
|
|
@@ -335,7 +335,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
|
|
|
|
|
it('keeps only the latest successful request anchor across model switches', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('switch'))
|
|
|
|
|
const session = Session.create(SessionId('switch'))
|
|
|
|
|
const alphaHeader = header('alpha', { system: 'same envelope' })
|
|
|
|
|
appendSuccessfulCall(session, alphaHeader, { usage: USAGE, providerText: 'alpha' })
|
|
|
|
|
expect(service.measure(session).baseline).toMatchObject({ kind: 'usage', tokens: 34 })
|
|
|
|
@@ -356,7 +356,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
|
|
|
|
|
it('invalidates usage for any canonical envelope change or explicit override', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const session = new Session(SessionId('envelope'))
|
|
|
|
|
const session = Session.create(SessionId('envelope'))
|
|
|
|
|
const anchoredHeader = header('deepseek-v4-flash', { system: 'one' })
|
|
|
|
|
appendSuccessfulCall(session, anchoredHeader, { usage: USAGE })
|
|
|
|
|
expect(service.measure(session, { ...anchoredHeader, tools: [] }).baseline.kind).toBe('usage')
|
|
|
|
@@ -375,7 +375,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('folds the latest full header snapshot into the effective envelope', () => {
|
|
|
|
|
const session = new Session(SessionId('header-snapshot'))
|
|
|
|
|
const session = Session.create(SessionId('header-snapshot'))
|
|
|
|
|
appendHeader(session, header('deepseek-v4-flash'))
|
|
|
|
|
session.append('request/header', {
|
|
|
|
|
header: header('deepseek-v4-pro'),
|
|
|
|
@@ -388,7 +388,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
|
|
|
|
|
it('replays seeded append and replace operations with signed deltas', () => {
|
|
|
|
|
const service = meter()
|
|
|
|
|
const original = new Session(SessionId('surface-original'))
|
|
|
|
|
const original = Session.create(SessionId('surface-original'))
|
|
|
|
|
appendSuccessfulCall(original, header('deepseek-v4-flash'), {
|
|
|
|
|
usage: USAGE,
|
|
|
|
|
providerText: 'long provider answer '.repeat(100),
|
|
|
|
@@ -397,7 +397,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
content: [{ type: 'text', text: 'new tail' }],
|
|
|
|
|
source: { kind: 'user' },
|
|
|
|
|
}), { surfaceOp: 'append' })
|
|
|
|
|
const seeded = new Session(SessionId('surface-seeded'), original.events)
|
|
|
|
|
const seeded = Session.create(SessionId('surface-seeded'), original.events)
|
|
|
|
|
const before = service.measure(seeded)
|
|
|
|
|
expect(before.nodes).toHaveLength(2)
|
|
|
|
|
expect(before.surfaceDeltaTokens).toBeGreaterThan(0)
|
|
|
|
@@ -423,7 +423,7 @@ describe('replay anchors and surface folds', () => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('prices an empty assistant surface anchor as zero', () => {
|
|
|
|
|
const session = new Session(SessionId('empty-assistant'))
|
|
|
|
|
const session = Session.create(SessionId('empty-assistant'))
|
|
|
|
|
appendSuccessfulCall(session, header('deepseek-v4-flash'), {
|
|
|
|
|
providerText: '',
|
|
|
|
|
durableText: '',
|
|
|
|
@@ -444,7 +444,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it('rejects an assistant without its step boundary transactionally', () => {
|
|
|
|
|
const session = new Session(SessionId('bad-step'))
|
|
|
|
|
const session = Session.create(SessionId('bad-step'))
|
|
|
|
|
appendHeader(session, header('deepseek-v4-flash'))
|
|
|
|
|
session.append('assistant/message', {
|
|
|
|
|
turn: 1,
|
|
|
|
@@ -462,7 +462,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('clears completed step boundaries and rejects overlapping or late step events', () => {
|
|
|
|
|
const overlapping = new Session(SessionId('overlapping-step'))
|
|
|
|
|
const overlapping = Session.create(SessionId('overlapping-step'))
|
|
|
|
|
overlapping.append('step/start', { turn: 1, step: 1 })
|
|
|
|
|
overlapping.append('step/start', { turn: 1, step: 2 })
|
|
|
|
|
expectRepeatedFailure(
|
|
|
|
@@ -471,7 +471,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
/arrived before turn 1\/step 1 ended/,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const late = new Session(SessionId('late-assistant'))
|
|
|
|
|
const late = Session.create(SessionId('late-assistant'))
|
|
|
|
|
late.append('step/start', { turn: 1, step: 1 })
|
|
|
|
|
appendHeader(late, header('deepseek-v4-flash'))
|
|
|
|
|
late.append('step/end', { turn: 1, step: 1 })
|
|
|
|
@@ -493,7 +493,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
/no matching step\/start/,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const mismatchedEnd = new Session(SessionId('mismatched-end'))
|
|
|
|
|
const mismatchedEnd = Session.create(SessionId('mismatched-end'))
|
|
|
|
|
mismatchedEnd.append('step/start', { turn: 1, step: 1 })
|
|
|
|
|
mismatchedEnd.append('step/end', { turn: 1, step: 2 })
|
|
|
|
|
expectRepeatedFailure(
|
|
|
|
@@ -532,7 +532,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
for (const testCase of cases) {
|
|
|
|
|
const session = new Session(SessionId(`bad-source-${testCase.name}`))
|
|
|
|
|
const session = Session.create(SessionId(`bad-source-${testCase.name}`))
|
|
|
|
|
session.append('step/start', { turn: 1, step: 1 })
|
|
|
|
|
appendHeader(session, header('deepseek-v4-flash'))
|
|
|
|
|
const sourceEventSeqs = testCase.appendSource(session)
|
|
|
|
@@ -554,7 +554,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('rejects repeated and non-earlier assistant provenance', () => {
|
|
|
|
|
const duplicate = new Session(SessionId('duplicate-source'))
|
|
|
|
|
const duplicate = Session.create(SessionId('duplicate-source'))
|
|
|
|
|
duplicate.append('step/start', { turn: 1, step: 1 })
|
|
|
|
|
appendHeader(duplicate, header('deepseek-v4-flash'))
|
|
|
|
|
const source = duplicate.append('assistant/chunk', {
|
|
|
|
@@ -584,7 +584,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
})
|
|
|
|
|
expect(() => meter().measure(duplicate)).toThrow(/repeats source seq/)
|
|
|
|
|
|
|
|
|
|
const future = new Session(SessionId('future-source'))
|
|
|
|
|
const future = Session.create(SessionId('future-source'))
|
|
|
|
|
future.append('step/start', { turn: 1, step: 1 })
|
|
|
|
|
appendHeader(future, header('deepseek-v4-flash'))
|
|
|
|
|
appendUnchecked(future, {
|
|
|
|
@@ -611,7 +611,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('does not partially apply a malformed assistant replacement', () => {
|
|
|
|
|
const session = new Session(SessionId('transactional-replace'))
|
|
|
|
|
const session = Session.create(SessionId('transactional-replace'))
|
|
|
|
|
session.append('user/message', createUserMessage({
|
|
|
|
|
content: [{ type: 'text', text: 'head' }],
|
|
|
|
|
source: { kind: 'user' },
|
|
|
|
@@ -638,7 +638,7 @@ describe('malformed replay and listener lifecycle', () => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('rejects corrupt replacement ranges without advancing the replay cursor', () => {
|
|
|
|
|
const session = new Session(SessionId('bad-replace'))
|
|
|
|
|
const session = Session.create(SessionId('bad-replace'))
|
|
|
|
|
const head = session.append('user/message', createUserMessage({
|
|
|
|
|
content: [{ type: 'text', text: 'head' }],
|
|
|
|
|
source: { kind: 'user' },
|
|
|
|
|