Files
dsh-context/tests/host/timeline.spec.ts
T
bowenliang123 e421a35b3b feat(client): split the Current Context reserve into headroom and output masks
The Current Context bar showed a single hatched band mirroring dsh's
default 80% threshold ratio, which reads wrong on any window where the
pressure budget binds instead (small windows, or a large routed output
cap). It now renders the two real reservations the harness spends the
top of the window on, priced by dsh-compaction-basic's own min() rule:

- the compaction headroom mask (mirrored default 65,536 tokens), then
- the routed request's output reservation, read from the durable
  request/header's materialized config.maxTokens rather than guessed.

The output cap folds off request/header at fold time, so the timeline
projection's stateVersion bumps 27 → 28 to refold cached rows from the
durable log. Geometry lives in a new client reserve module; the bar
tiles [threshold, window] with the two adjacent masks, each with its
own name-plus-length tooltip.
2026-10-13 14:47:28 +08:00

123 lines
5.5 KiB
TypeScript

// The contextTimeline projection unit (src/host/timeline.ts) — the projection-definition contract surface (stateSchema + required wire),
// its schemas, and the config-resolved retention bounds, over a real folded log. Fold semantics themselves live in fold.ts.
import assert from 'node:assert/strict'
import { describe, test } from 'vitest'
import { createContextTimelineDefinition } from '../../src/host/timeline'
import type { ContextTimeline, SurfaceNode } from '../../src/shared/types'
import { driveTimeline } from './helpers/projection'
import {
assistantMessage,
compaction,
header,
planMode,
requestContext,
stepEnd,
stepStart,
systemMessage,
toolCall,
toolResult,
userMessage,
} from './helpers/events'
import type { TimelineEvent } from '../../src/host/fold'
/** A realistic session log touching every envelope family the fold serves. */
function realLog(): TimelineEvent[] {
return [
header(1, {
tools: [{ name: 'bash', description: 'run a command' }],
model: 'deepseek-v4-flash',
provider: 'deepseek',
}),
systemMessage(2),
requestContext(3, { contextWindow: 128000 }),
stepStart(4),
userMessage(5, [{ type: 'text', text: 'hello there' }], { kind: 'user' }),
assistantMessage(6, { turn: 1, step: 0, usage: { inputTokens: 10, outputTokens: 5, cacheReadTokens: 3 } }),
toolCall(7, { callId: 'c1', name: 'bash' }),
toolResult(8, { callId: 'c1', content: [{ type: 'text', text: 'ok' }] }),
stepEnd(9),
assistantMessage(10, { turn: 1, step: 1, usage: { inputTokens: 20, outputTokens: 8 } }),
compaction(11, 'summary', { shadowedTokenCount: 12, shadowedSeqs: [5] }),
planMode(12, { active: true }),
]
}
describe('createContextTimelineDefinition', () => {
test('carries the supported projection contract on one unit', () => {
const def = createContextTimelineDefinition({}, () => false)
assert.equal(def.key, 'contextTimeline')
assert.equal(def.stateVersion, 28)
assert.equal(typeof def.init, 'function')
assert.equal(typeof def.apply, 'function')
// The supported registry contract: stateSchema + a REQUIRED wire block.
assert.equal(typeof def.stateSchema.parse, 'function')
assert.equal(typeof def.wire.viewSchema.safeParse, 'function')
assert.equal(typeof def.wire.view, 'function')
})
test('the wire schema accepts a real folded view; the state schema accepts every intermediate state', () => {
const def = createContextTimelineDefinition({}, () => false)
const drive = driveTimeline(realLog())
const parsed = def.wire.viewSchema.safeParse(drive.view)
assert.equal(parsed.success, true, 'a real folded view validates')
const view = drive.view
assert.equal(view.ok, true)
assert.equal(view.model, 'deepseek-v4-flash')
assert.equal(view.provider, 'deepseek')
assert.equal(view.contextWindow, 128000)
assert.equal(view.humanInputs, 1, 'the canonical log\'s one user message')
assert.ok(view.nodes.length > 0)
assert.ok(view.requests.length > 0)
assert.ok(view.events.length > 0)
// The duration overlay's per-request step active time (RequestRecord.activeMs): the first
// request's step ran start (tick 4s) → end (tick 9s) with its bash call inside and no user
// waits; the second folded after stepEnd consumed the slot.
assert.equal(view.requests[0].activeMs, 5000, 'step start → step end, the tool run included')
assert.equal(view.requests[1].activeMs, undefined, 'no open step slot, no stamp')
for (const [index, state] of drive.states.entries()) {
def.stateSchema.parse(structuredClone(state)) // throws on drift
assert.ok(true, `state ${index} validates`)
}
assert.equal(def.wire.viewSchema.safeParse(def.wire.view(drive.state)).success, true)
})
test('the wire schema rejects drift', () => {
const def = createContextTimelineDefinition({}, () => false)
const drive = driveTimeline(realLog())
const extra = structuredClone(drive.view) as unknown as Record<string, unknown>
extra.bogus = 1
assert.equal(def.wire.viewSchema.safeParse(extra).success, false, 'strict: unknown keys rejected')
const badCat = structuredClone(drive.view)
;(badCat.nodes[0] as SurfaceNode).cat = 'weird' as SurfaceNode['cat']
assert.equal(def.wire.viewSchema.safeParse(badCat).success, false, 'the cat enum rejects unknown categories')
const badTokens = structuredClone(drive.view)
badTokens.nodes[0].tokens = -1
assert.equal(def.wire.viewSchema.safeParse(badTokens).success, false, 'negative token counts rejected')
})
test('maxNodes bounds the served surface nodes', () => {
const events: TimelineEvent[] = [
header(1, { model: 'm', provider: 'p' }),
userMessage(2, [{ type: 'text', text: 'one' }], { kind: 'user' }),
userMessage(3, [{ type: 'text', text: 'two' }], { kind: 'user' }),
userMessage(4, [{ type: 'text', text: 'three' }], { kind: 'user' }),
userMessage(5, [{ type: 'text', text: 'four' }], { kind: 'user' }),
]
const bounded = driveTimeline(events, { maxNodes: 2 })
assert.equal(bounded.view.nodes.length, 2, 'only the newest tail is served')
assert.deepEqual(bounded.view.nodes.map(n => n.seq), [4, 5])
assert.equal(bounded.view.droppedNodes, 2)
assert.equal(bounded.view.surfaceFloor, 3, 'the newest unserved live seq')
const unbounded: ContextTimeline = driveTimeline(events).view
assert.equal(unbounded.nodes.length, 4, 'default bounds serve every live node')
assert.equal(unbounded.droppedNodes, 0)
})
})