feat(client): true-size reserve masks, with a trigger line when the ratio detaches it
This commit is contained in:
1 parent
1358603759
commit
863d3cdcdc
9 files changed
+120
-51
No files matched your search
@@ -145,7 +145,7 @@ The trend chart's duration overlay (the card's Duration toggle: each request's s
|
||||
|
||||
The session node's answers tally (`answers` on the `contextTimeline` head — one per assistant message carrying a non-blank text block; steps that only dispatched tool calls are work, not replies) bumps the timeline projection's `stateVersion` (26 → 27): it is a running total over the complete log that later events cannot backfill for sessions folded before the field existed (the v16 `humanInputs` precedent), so on upgrade every cached timeline row is invalidated and refolded from the durable log, while the v20 warm-up rebuilds idle sessions' rows the first time the page opens. On the wire the field is additive-optional: a row folded before it existed serves without it and the card degrades to a zero figure. The head's sibling `counts.skills` figure (the distinct loaded-skill names) needed no bump of its own — it is derived at view time over the retained events already living in every cached row's state (skill-tagged inject events since v19), so a pre-field row recomputes the exact tally the moment this build serves it.
|
||||
|
||||
The Current Context bar's two auto-compaction reserve masks need the routed request's output cap, which bumps the timeline projection's `stateVersion` (27 → 28): the cap is the newest `request/header` envelope's materialized `config.maxTokens`, folded last-wins exactly as the compaction backend's own `reservedCompletionTokens` reads it, and a header event already folded can never be replayed into a cached row while its session is idle; on upgrade every cached timeline row is invalidated and refolded from the durable log, while the v20 warm-up rebuilds idle sessions' rows the first time the page opens. On the wire the field is additive-optional: a row folded before it existed, or a log whose header carries no cap, serves without it and the bar paints the headroom mask alone (the client re-derives the reserve per serve — `src/client/reserve.ts`), the same sanitizer contract every other scalar rides.
|
||||
The Current Context bar's two auto-compaction reserve masks need the routed request's output cap, which bumps the timeline projection's `stateVersion` (27 → 28): the cap is the newest `request/header` envelope's materialized `config.maxTokens`, folded last-wins exactly as the compaction backend's own `reservedCompletionTokens` reads it, and a header event already folded can never be replayed into a cached row while its session is idle; on upgrade every cached timeline row is invalidated and refolded from the durable log, while the v20 warm-up rebuilds idle sessions' rows the first time the page opens. On the wire the field is additive-optional: a row folded before it existed, or a log whose header carries no cap, serves without it and the bar paints the headroom mask without the output one (the client re-derives the reserve per serve — `src/client/reserve.ts`), the same sanitizer contract every other scalar rides.
|
||||
|
||||
The Fleet tab's per-agent detail (delegation prompt, descriptor composition, latest reply, inter-agent messages, and the lead's roster facts) rides the plugin's `/api/dsh-context/fleet` fetch route — the same authenticated `/api` fence, Connection exact-route registry, and cold-read gate as the detail route, folding nothing token-shaped of its own: it lifts `subagent/descriptor`, `team/member`, and `user/message` relay/mailbox/settled records out of one `sessionQuery.observeSession` read per session (live-preferred, so live and cold sessions share the path). Every seam degrades independently: a deployment without the route (or a skipped cold read) renders the inspector's core and hides the detail sections; a harness without the experimental Agent Teams plugin serves no `agentTeam` projection, so the members board and task board simply never render; the relay/mailbox/settled source kinds absent from a session's log yield an empty comms timeline, not an error. Sender-framing preambles ("Agent <id> sent a message:", "Team message <id> from <name>:", "Team message from <name>:") strip at extraction; the `subagent-settled` English boilerplate maps to localized variants at render, with unrecognized phrasings falling back to the raw text.
|
||||
|
||||
|
||||
@@ -46,17 +46,17 @@ export interface StackedBarProps {
|
||||
/** Render the hover tooltip (default true); a bar that only MIRRORS another card's hover turns it off, so the tooltip
|
||||
* floats only over the surface the pointer actually rests on. */
|
||||
tip?: boolean
|
||||
/** Optional auto-compaction reserve: the two masks right of the pressure trigger — the compaction
|
||||
* headroom, then the routed output reservation at the window's end (reserve.ts derives them). Laid
|
||||
* out in WINDOW tokens and rendered only when `max` (the window) is positive. */
|
||||
/** Optional auto-compaction reserve (reserve.ts derives the geometry): the two masks tiling the
|
||||
* window's tail — headroom, then the output reservation — plus the trigger's line when it detaches.
|
||||
* Laid out in WINDOW tokens and rendered only when `max` (the window) is positive. */
|
||||
reserve?: ContextReserve
|
||||
}
|
||||
|
||||
export function makeStackedBar(kit: ViewKit): (props: StackedBarProps) => ReactElement {
|
||||
const { t, fmt, catLabel } = kit
|
||||
return function StackedBar(props: StackedBarProps): ReactElement {
|
||||
// The reserve-hover key lives here so the single tooltip slot serves both the segments and the masks.
|
||||
const [reserveOn, setReserveOn] = useState<ReserveMask['key'] | null>(null)
|
||||
// The reserve-hover key lives here so the single tooltip slot serves segments, masks, and the trigger line.
|
||||
const [reserveOn, setReserveOn] = useState<ReserveMask['key'] | 'trigger' | null>(null)
|
||||
const wrapRef = useRef<HTMLDivElement | null>(null)
|
||||
const tipRef = useRef<HTMLDivElement | null>(null)
|
||||
const [tipShift, setTipShift] = useState(0)
|
||||
@@ -94,37 +94,55 @@ export function makeStackedBar(kit: ViewKit): (props: StackedBarProps) => ReactE
|
||||
|
||||
// The masks lay out in WINDOW units scaled onto whatever track the bar spans, so they keep the same
|
||||
// physical slice with or without a free track (once used exceeds the window, the stripes sit over the
|
||||
// outermost segments). The two tile `[threshold, window]` end to end, and a mask nothing wide enough
|
||||
// to hover is dropped rather than rendered sub-pixel.
|
||||
const reserve = props.reserve !== undefined && props.max !== undefined && props.max > 0 ? props.reserve : undefined
|
||||
// outermost segments). They tile the window's tail at their true sizes — [window − output − headroom,
|
||||
// window] — and a mask nothing wide enough to hover is dropped rather than rendered sub-pixel.
|
||||
const win = props.max !== undefined && props.max > 0 ? props.max : undefined
|
||||
const reserve = win === undefined ? undefined : props.reserve
|
||||
const trackPct = (tokens: number): number => Math.round(Math.max(0, Math.min(100, tokens / scale * 100)) * 10) / 10
|
||||
// The headroom mask's left edge IS the trigger position, so read it off the same projection the masks use
|
||||
// rather than a second ratio — that one is clamped to the window, so no impossible percent reaches the copy.
|
||||
// Read the trigger off the same projection the masks use — that one is clamped to the window,
|
||||
// so no impossible percent reaches the copy.
|
||||
const triggerPct = reserve === undefined ? 0 : trackPct(reserve.threshold)
|
||||
const masks: ReserveMask[] = []
|
||||
if (reserve !== undefined) {
|
||||
let triggerDetached = false
|
||||
if (reserve !== undefined && win !== undefined) {
|
||||
const maskStart = win - reserve.output - reserve.headroom
|
||||
const pieces = [
|
||||
{ key: 'headroom' as const, label: t('overview.reserveHeadroom'), tokens: reserve.headroom, from: reserve.threshold },
|
||||
{ key: 'output' as const, label: t('overview.reserveOutput'), tokens: reserve.output, from: reserve.threshold + reserve.headroom },
|
||||
{ key: 'headroom' as const, label: t('overview.reserveHeadroom'), tokens: reserve.headroom, from: maskStart },
|
||||
{ key: 'output' as const, label: t('overview.reserveOutput'), tokens: reserve.output, from: win - reserve.output },
|
||||
]
|
||||
for (const piece of pieces) {
|
||||
const left = trackPct(piece.from)
|
||||
const width = trackPct(piece.from + piece.tokens) - left
|
||||
if (width > 0) masks.push({ key: piece.key, label: piece.label, tokens: piece.tokens, left, width })
|
||||
}
|
||||
triggerDetached = reserve.threshold < maskStart
|
||||
}
|
||||
|
||||
// Every reserve piece — masks and the trigger line — shares the one hover key and pointer handling.
|
||||
const enterReserve = (key: ReserveMask['key'] | 'trigger') => (): void => {
|
||||
setReserveOn(key)
|
||||
if (props.onHoverKey !== undefined) props.onHoverKey(null)
|
||||
}
|
||||
const leaveReserve = (): void => { setReserveOn(null) }
|
||||
|
||||
// The tooltip is DERIVED from the shared hover key, so a segment and its legend chip light the same segment with the same tooltip;
|
||||
// the wrapper keeps it outside the clipped stack; a hovered reserve mask overrides the slot with its own rows. Every figure NAMES its
|
||||
// denominator — the segments share the USED total, the free track the WINDOW, the masks state only where they sit in the window.
|
||||
// the wrapper keeps it outside the clipped stack; a hovered reserve piece (mask or trigger line) overrides the slot with its own
|
||||
// rows. Every figure NAMES its denominator — the segments share the USED total, the free track and the trigger line the WINDOW.
|
||||
let tip: BarTip | null = null
|
||||
const hoveredMask = reserveOn === null ? undefined : masks.find(m => m.key === reserveOn)
|
||||
if (hoveredMask !== undefined) {
|
||||
if (reserveOn === 'trigger' && reserve !== undefined && triggerDetached) {
|
||||
tip = {
|
||||
head: t('overview.reserveTrigger'),
|
||||
figure: `${fmt(reserve.threshold)} · ${triggerPct}% ${t('overview.ofWindow')}`,
|
||||
note: t('overview.reserveTriggerTip'),
|
||||
leftPct: triggerPct,
|
||||
}
|
||||
} else if (hoveredMask !== undefined) {
|
||||
tip = {
|
||||
head: hoveredMask.label,
|
||||
figure: fmt(hoveredMask.tokens),
|
||||
note: hoveredMask.key === 'headroom'
|
||||
? t('overview.reserveHeadroomTip', { p: triggerPct })
|
||||
? (triggerDetached ? t('overview.reserveHeadroomBuffer') : t('overview.reserveHeadroomTip', { p: triggerPct }))
|
||||
: t('overview.reserveOutputTip'),
|
||||
leftPct: hoveredMask.left + hoveredMask.width / 2,
|
||||
}
|
||||
@@ -225,13 +243,18 @@ export function makeStackedBar(kit: ViewKit): (props: StackedBarProps) => ReactE
|
||||
key={m.key}
|
||||
className={`lc-reserve lc-reserve-${m.key}`}
|
||||
style={{ left: `${m.left}%`, width: `${m.width}%` }}
|
||||
onMouseEnter={() => {
|
||||
setReserveOn(m.key)
|
||||
if (props.onHoverKey !== undefined) props.onHoverKey(null)
|
||||
}}
|
||||
onMouseLeave={() => { setReserveOn(null) }}
|
||||
onMouseEnter={enterReserve(m.key)}
|
||||
onMouseLeave={leaveReserve}
|
||||
/>
|
||||
))}
|
||||
{triggerDetached ? (
|
||||
<div
|
||||
className="lc-trigger"
|
||||
style={{ left: `${triggerPct}%` }}
|
||||
onMouseEnter={enterReserve('trigger')}
|
||||
onMouseLeave={leaveReserve}
|
||||
/>
|
||||
) : null}
|
||||
{/* The occupied-region frame: painted last so its border stays above the segments; always mounted (`.lc-occupied-box-on` toggles
|
||||
opacity) so it fades out on leave instead of unmounting instantly.
|
||||
*/}
|
||||
|
||||
@@ -22,7 +22,10 @@ export const DICT_EN = {
|
||||
'overview.reserveHeadroom': 'Compaction headroom',
|
||||
'overview.reserveOutput': 'Max output tokens',
|
||||
'overview.reserveHeadroomTip': 'Auto-compaction fires at {p}% of the window',
|
||||
'overview.reserveHeadroomBuffer': 'Buffer kept free ahead of the output reservation',
|
||||
'overview.reserveOutputTip': 'This reply\'s output is reserved at the window\'s end',
|
||||
'overview.reserveTrigger': 'Auto-compaction trigger',
|
||||
'overview.reserveTriggerTip': 'Compaction fires when the used tokens reach this line',
|
||||
'stats.title': 'Context Stats',
|
||||
'stats.session': 'Current Session',
|
||||
'stats.turns': 'Turns',
|
||||
|
||||
@@ -19,7 +19,10 @@ export const DICT_ZH = {
|
||||
'overview.reserveHeadroom': '压缩余量',
|
||||
'overview.reserveOutput': '最大输出预留',
|
||||
'overview.reserveHeadroomTip': '自动压缩在窗口的 {p}% 处触发',
|
||||
'overview.reserveHeadroomBuffer': '在输出预留之前留出的缓冲',
|
||||
'overview.reserveOutputTip': '本次回复的输出预留在窗口末尾',
|
||||
'overview.reserveTrigger': '自动压缩触发线',
|
||||
'overview.reserveTriggerTip': '已用量到达此线时触发压缩',
|
||||
'stats.title': '上下文统计',
|
||||
'stats.session': '当前会话',
|
||||
'stats.turns': '轮次',
|
||||
|
||||
+11
-9
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* The auto-compaction reserve the Current Context bar masks: the window the session is kept out of
|
||||
* once compaction would fire, split into its two parts — the compaction headroom and the routed
|
||||
* request's output reservation.
|
||||
* The auto-compaction reserve the Current Context bar masks: the window's tail the session is kept
|
||||
* out of, at its two true sizes — the compaction headroom buffer, then the routed request's output
|
||||
* reservation at the window's end.
|
||||
*
|
||||
* dsh-compaction-basic prices its pressure trigger as
|
||||
* `thresholdTokens = floor(min(contextWindow × thresholdRatio, contextWindow − reservedOutput − headroomTokens))`
|
||||
@@ -21,9 +21,11 @@ export const COMPACT_HEADROOM_TOKENS = 65_536
|
||||
|
||||
/** Where the reserve starts and what it is made of, in WINDOW tokens. */
|
||||
export interface ContextReserve {
|
||||
/** Window tokens at which automatic pressure compaction triggers — the masks' left edge. */
|
||||
/** Window tokens at which automatic pressure compaction triggers: the headroom mask's left edge
|
||||
* when the pressure budget binds, strictly left of the masks when the window fraction does. */
|
||||
threshold: number
|
||||
/** Window tokens between the trigger and the output reservation — the compaction-headroom mask. */
|
||||
/** The compaction-headroom mask — always the mirrored policy value, the buffer between the
|
||||
* pressure budget and the output reservation. */
|
||||
headroom: number
|
||||
/** The routed request's output reservation at the window's end — the max-output mask. */
|
||||
output: number
|
||||
@@ -31,9 +33,9 @@ export interface ContextReserve {
|
||||
|
||||
/** Resolve one window's reserve, or undefined when no positive window is known OR the harness
|
||||
* itself refuses to configure pressure compaction for that route (see the budget check below). The
|
||||
* masks tile `[threshold, window]` end to end; `maxOutputTokens` is untrusted wire input, and
|
||||
* anything but a positive finite cap reserves nothing (dsh's own fallback order: envelope cap,
|
||||
* else zero). */
|
||||
* masks tile the window's tail `[window − output − headroom, window]` end to end, each at its true
|
||||
* size; `maxOutputTokens` is untrusted wire input, and anything but a positive finite cap reserves
|
||||
* nothing (dsh's own fallback order: envelope cap, else zero). */
|
||||
export function reserveGeometry(
|
||||
window: number | undefined,
|
||||
maxOutputTokens: number | undefined,
|
||||
@@ -50,5 +52,5 @@ export function reserveGeometry(
|
||||
const pressureBudget = window - output - COMPACT_HEADROOM_TOKENS
|
||||
if (pressureBudget <= 0) return undefined
|
||||
const threshold = Math.min(Math.floor(window * COMPACT_THRESHOLD_RATIO), pressureBudget)
|
||||
return { threshold, headroom: window - output - threshold, output }
|
||||
return { threshold, headroom: COMPACT_HEADROOM_TOKENS, output }
|
||||
}
|
||||
@@ -25,6 +25,10 @@
|
||||
.lc-reserve { position: absolute; top: 0; bottom: 0; z-index: 1; pointer-events: auto; cursor: help; }
|
||||
.lc-reserve-headroom { background: repeating-linear-gradient(45deg, color-mix(in srgb, var(--dsw-alias-state-warn-primary) 24%, transparent) 0 5px, transparent 5px 10px); }
|
||||
.lc-reserve-output { background: repeating-linear-gradient(-45deg, color-mix(in srgb, var(--dsw-alias-state-business-primary) 24%, transparent) 0 5px, transparent 5px 10px); }
|
||||
/* The trigger line (painted only when it detaches from the masks — reserve.ts): a 2px rule inside a
|
||||
wider lane so the hover target stays hittable; unanimated like the masks, same warn hue. */
|
||||
.lc-trigger { position: absolute; top: 0; bottom: 0; width: 9px; transform: translateX(-50%); z-index: 1; pointer-events: auto; cursor: help; }
|
||||
.lc-trigger::after { content: ''; position: absolute; top: 0; bottom: 0; left: 50%; width: 2px; margin-left: -1px; background: var(--dsw-alias-state-warn-primary); }
|
||||
/* Dashed border, not box-shadow: a shadow cannot dash. */
|
||||
.lc-stacked-free-on { border: 2px dashed var(--dsw-alias-label-secondary); border-radius: 3px; }
|
||||
.lc-stacked-dim .lc-stacked-seg { opacity: 0.35; }
|
||||
|
||||
@@ -233,7 +233,7 @@ describe('StackedBar hover link', () => {
|
||||
describe('StackedBar reserve masks', () => {
|
||||
const RESERVE = { threshold: 800, headroom: 100, output: 100 }
|
||||
|
||||
test('the two masks tile the window tail; each hover shows its own figure, trigger note and anchor', async () => {
|
||||
test('a bound pressure budget: the two masks tile the window tail from the trigger, no line', async () => {
|
||||
const m = await mount(h(HoverHarness, { parts: [part('user', 100)], max: 1000, reserve: RESERVE }))
|
||||
const headroom = query(m.container, '.lc-reserve-headroom')
|
||||
assert.equal(headroom.style.left, '80%')
|
||||
@@ -241,6 +241,8 @@ describe('StackedBar reserve masks', () => {
|
||||
const output = query(m.container, '.lc-reserve-output')
|
||||
assert.equal(output.style.left, '90%')
|
||||
assert.equal(output.style.width, '10%')
|
||||
// The headroom mask's own left edge IS the trigger, so no separate line is drawn.
|
||||
assert.equal(queryAll(m.container, '.lc-trigger').length, 0)
|
||||
await hover(headroom)
|
||||
const tip = query(m.container, '.lc-bar-tip')
|
||||
assert.ok(tip.className.includes('lc-bar-tip-on'))
|
||||
@@ -258,6 +260,32 @@ describe('StackedBar reserve masks', () => {
|
||||
await m.unmount()
|
||||
})
|
||||
|
||||
test('a bound window fraction: true-size masks at the window tail, the trigger as its own line', async () => {
|
||||
// threshold 800 sits strictly left of the masks' 840 edge: headroom + output (160) < 20% of the window.
|
||||
const reserve = { threshold: 800, headroom: 60, output: 100 }
|
||||
const m = await mount(h(HoverHarness, { parts: [part('user', 100)], max: 1000, reserve }))
|
||||
const headroom = query(m.container, '.lc-reserve-headroom')
|
||||
assert.equal(headroom.style.left, '84%')
|
||||
assert.equal(headroom.style.width, '6%')
|
||||
const output = query(m.container, '.lc-reserve-output')
|
||||
assert.equal(output.style.left, '90%')
|
||||
assert.equal(output.style.width, '10%')
|
||||
const line = query(m.container, '.lc-trigger')
|
||||
assert.equal(line.style.left, '80%')
|
||||
// The headroom mask describes only itself; the trigger fact belongs to the line.
|
||||
await hover(headroom)
|
||||
assert.deepEqual(tipRows(query(m.container, '.lc-bar-tip')), ['Compaction headroom', '60', 'Buffer kept free ahead of the output reservation'])
|
||||
await unhover(headroom)
|
||||
await hover(line)
|
||||
const tip = query(m.container, '.lc-bar-tip')
|
||||
assert.deepEqual(tipRows(tip), ['Auto-compaction trigger', '800 · 80% of window', 'Compaction fires when the used tokens reach this line'])
|
||||
assert.equal(tip.style.left, '80%')
|
||||
assert.equal(query(m.container, '.lc-stacked').className, 'lc-stacked') // hoverKey cleared
|
||||
await unhover(line)
|
||||
assert.equal(query(m.container, '.lc-bar-tip').className, 'lc-tip lc-bar-tip')
|
||||
await m.unmount()
|
||||
})
|
||||
|
||||
test('a zero-extent mask is dropped; an output-only reserve renders the rightmost mask alone', async () => {
|
||||
const m = await mount(h(HoverHarness, {
|
||||
parts: [part('user', 100)],
|
||||
@@ -265,12 +293,14 @@ describe('StackedBar reserve masks', () => {
|
||||
reserve: { threshold: 1000, headroom: 0, output: 0 },
|
||||
}))
|
||||
assert.equal(queryAll(m.container, '.lc-reserve').length, 0)
|
||||
assert.equal(queryAll(m.container, '.lc-trigger').length, 0)
|
||||
await m.update(h(HoverHarness, {
|
||||
parts: [part('user', 100)],
|
||||
max: 1000,
|
||||
reserve: { threshold: 900, headroom: 0, output: 100 },
|
||||
}))
|
||||
assert.equal(queryAll(m.container, '.lc-reserve-headroom').length, 0)
|
||||
assert.equal(queryAll(m.container, '.lc-trigger').length, 0)
|
||||
const output = query(m.container, '.lc-reserve-output')
|
||||
assert.equal(output.style.left, '90%')
|
||||
assert.equal(output.style.width, '10%')
|
||||
@@ -294,8 +324,10 @@ describe('StackedBar reserve masks', () => {
|
||||
const reserve = RESERVE
|
||||
const m = await mount(h(StackedBar, { parts: [part('user', 100)], reserve }))
|
||||
assert.equal(queryAll(m.container, '.lc-reserve').length, 0)
|
||||
assert.equal(queryAll(m.container, '.lc-trigger').length, 0)
|
||||
await m.update(h(StackedBar, { parts: [part('user', 100)], max: 0, reserve }))
|
||||
assert.equal(queryAll(m.container, '.lc-reserve').length, 0)
|
||||
assert.equal(queryAll(m.container, '.lc-trigger').length, 0)
|
||||
await m.unmount()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -138,16 +138,16 @@ describe('headlineOf reserve', () => {
|
||||
assert.deepEqual(h.reserve, { threshold: 678_464, headroom: 65_536, output: 256_000 })
|
||||
})
|
||||
|
||||
test('without an output cap only the headroom mask is left (the whole tail up to the ratio)', () => {
|
||||
test('without an output cap only the headroom mask is left (at its true size, the trigger detached)', () => {
|
||||
const h = headlineOf(timeline({ contextWindow: 1_000_000 }), null)
|
||||
assert.deepEqual(h.reserve, { threshold: 800_000, headroom: 200_000, output: 0 })
|
||||
assert.deepEqual(h.reserve, { threshold: 800_000, headroom: 65_536, output: 0 })
|
||||
})
|
||||
|
||||
test('a hostile or non-positive cap reserves nothing; no window yields no reserve at all', () => {
|
||||
const hostile = headlineOf(timeline({ contextWindow: 1_000_000, maxOutputTokens: 'junk' as unknown as number }), null)
|
||||
assert.deepEqual(hostile.reserve, { threshold: 800_000, headroom: 200_000, output: 0 })
|
||||
assert.deepEqual(hostile.reserve, { threshold: 800_000, headroom: 65_536, output: 0 })
|
||||
const zero = headlineOf(timeline({ contextWindow: 1_000_000, maxOutputTokens: 0 }), null)
|
||||
assert.deepEqual(zero.reserve, { threshold: 800_000, headroom: 200_000, output: 0 })
|
||||
assert.deepEqual(zero.reserve, { threshold: 800_000, headroom: 65_536, output: 0 })
|
||||
assert.equal(headlineOf(timeline({ maxOutputTokens: 256_000 }), null).reserve, undefined)
|
||||
})
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
// The auto-compaction reserve geometry (src/client/reserve.ts): dsh-compaction-basic's pressure
|
||||
// trigger priced against the session's real window and routed output cap, plus the mask extents the
|
||||
// composition bar paints. The two masks must always tile [threshold, window].
|
||||
// composition bar paints. The masks tile the window's tail [window − output − headroom, window] at
|
||||
// their true sizes; the trigger sits at or left of the headroom mask's left edge.
|
||||
|
||||
import assert from 'node:assert/strict'
|
||||
import { describe, test } from 'vitest'
|
||||
import { COMPACT_HEADROOM_TOKENS, COMPACT_THRESHOLD_RATIO, reserveGeometry } from '../../src/client/reserve'
|
||||
|
||||
/** The reserve always closes the window: trigger + headroom mask + output mask. */
|
||||
function tiles(reserve: NonNullable<ReturnType<typeof reserveGeometry>>, window: number): boolean {
|
||||
return reserve.threshold + reserve.headroom + reserve.output === window
|
||||
/** The trigger never crosses the masks: it IS the headroom mask's left edge when the pressure
|
||||
* budget binds, and sits strictly left of it when the window fraction binds. */
|
||||
function triggerAtOrLeftOfMasks(reserve: NonNullable<ReturnType<typeof reserveGeometry>>, window: number): boolean {
|
||||
return reserve.threshold <= window - reserve.output - reserve.headroom
|
||||
}
|
||||
|
||||
describe('reserveGeometry', () => {
|
||||
@@ -20,25 +22,25 @@ describe('reserveGeometry', () => {
|
||||
assert.equal(reserveGeometry(Number.POSITIVE_INFINITY, 256_000), undefined)
|
||||
})
|
||||
|
||||
test('the deepseek defaults: the pressure budget binds, and the headroom mask IS headroomTokens', () => {
|
||||
test('the deepseek defaults: the pressure budget binds, and the trigger is the masks\' left edge', () => {
|
||||
// W = 1,000,000, O = 256,000 (the routed envelope cap), B = 65,536 (dsh's default):
|
||||
// threshold = min(floor(W × 0.8), W − O − B) = min(800,000, 678,464).
|
||||
const reserve = reserveGeometry(1_000_000, 256_000)
|
||||
assert.deepEqual(reserve, { threshold: 678_464, headroom: COMPACT_HEADROOM_TOKENS, output: 256_000 })
|
||||
assert.ok(tiles(reserve!, 1_000_000))
|
||||
assert.ok(triggerAtOrLeftOfMasks(reserve!, 1_000_000))
|
||||
})
|
||||
|
||||
test('a small output cap leaves the ratio binding, and the headroom mask grows to the ratio slack', () => {
|
||||
// threshold = min(800,000, 926,464) = 800,000; the mask runs to the output reservation's edge.
|
||||
test('a small output cap leaves the ratio binding: the trigger detaches, the headroom keeps its true size', () => {
|
||||
// threshold = min(800,000, 926,464) = 800,000 — strictly left of the masks' 926,464 edge.
|
||||
const reserve = reserveGeometry(1_000_000, 8_000)
|
||||
assert.deepEqual(reserve, { threshold: 800_000, headroom: 192_000, output: 8_000 })
|
||||
assert.deepEqual(reserve, { threshold: 800_000, headroom: COMPACT_HEADROOM_TOKENS, output: 8_000 })
|
||||
assert.equal(reserve!.threshold, Math.floor(1_000_000 * COMPACT_THRESHOLD_RATIO))
|
||||
assert.ok(tiles(reserve!, 1_000_000))
|
||||
assert.ok(triggerAtOrLeftOfMasks(reserve!, 1_000_000))
|
||||
})
|
||||
|
||||
test('an unknown, non-positive, or non-finite output cap reserves nothing', () => {
|
||||
// No output reservation, so the ratio binds at 800,000 and the headroom mask is the rest.
|
||||
const expected = { threshold: 800_000, headroom: 200_000, output: 0 }
|
||||
test('an unknown, non-positive, or non-finite output cap reserves no output', () => {
|
||||
// No output reservation, so the ratio binds at 800,000 and the headroom mask stands alone.
|
||||
const expected = { threshold: 800_000, headroom: COMPACT_HEADROOM_TOKENS, output: 0 }
|
||||
for (const cap of [undefined, 0, -8_000, Number.NaN, Number.POSITIVE_INFINITY] as const) {
|
||||
assert.deepEqual(reserveGeometry(1_000_000, cap), expected, String(cap))
|
||||
}
|
||||
@@ -58,6 +60,6 @@ describe('reserveGeometry', () => {
|
||||
// One token of budget survives, so the masks come back — the headroom is exactly dsh's default.
|
||||
const tight = reserveGeometry(65_537, 0)
|
||||
assert.deepEqual(tight, { threshold: 1, headroom: COMPACT_HEADROOM_TOKENS, output: 0 })
|
||||
assert.ok(tiles(tight!, 65_537))
|
||||
assert.ok(triggerAtOrLeftOfMasks(tight!, 65_537))
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user