mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-19 17:11:42 -06:00
3d016975c3
* fix(codex): bound no-engine continuity projections to half the context window A degraded or absent context engine sends fresh-thread continuity through projectContextEngineAssemblyForCodex with the whole-window projection cap ((window - 20k) x 4 chars), so a large uncompacted transcript renders into a single turn/start input consuming up to 90% of the model context window. That turn fills its own native thread, the next turn's token fuse rotates it, and the following fresh thread re-projects the transcript again - observed as 11 near-window turn inputs on cold threads in one day (openclaw/openclaw#125254). Continuity projections now use a dedicated cap that reserves half the context token budget, so the fresh thread keeps headroom for later turns and the existing delta-resume path can actually engage. The active-engine projection path keeps its whole-window cap unchanged. Related: #125254 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN * fix(codex): size continuity projections from real token cost, not the optimistic estimate The continuity cap reserved half the context window in tokens but converted that budget to characters with APPROX_RENDERED_CHARS_PER_TOKEN = 4, so at a 258,400-token window it permitted 516,800 chars. A live projection measured 703,134 chars for 226,146 input tokens, meaning that cap really costs about 166k tokens (~64% of the window), not the intended 129.2k. Codex reports input tokens only after a turn and bounds turn input by characters, so the projection cannot be sized in verified tokens before it is sent. Convert the continuity budget at a conservative 3 chars/token instead, which holds the reserved half in real tokens at the densest ratio observed. Related: #125254 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN * fix(codex): scope the continuity sizing claim to the density it was measured at The half-window claim was stated as a guarantee, but the 3 chars/token conversion rests on one observed projection. Input that tokenizes more densely (CJK, base64, minified code) still exceeds the reserved half, so the constant is renamed to CONTINUITY_EMPIRICAL_CHARS_PER_TOKEN and its comment says plainly that it is an empirical floor rather than a bound. The invariant test is narrowed to the measured density, and a companion test pins the break-even ratio at 3 chars/token so the limitation is visible in the suite instead of implied. Choosing between a guaranteed worst-case bound and this empirical cap is a maintainer-owned tradeoff, left open on the PR. Related: #125254 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN * feat(codex): size continuity projections from the session's observed token density Each completed Codex turn now records a calibration sample on the thread binding: prompt chars actually sent vs the provider-reported input token cost (uncached + cache read + cache write). The no-engine continuity cap converts its half-window token budget at that observed ratio instead of a fixed chars-per-token guess, so capChars / ratio stays at the reserved budget for any content density - CJK, base64, and minified code included. The sample is captured before startup rotation so a rotated-away thread's density still sizes the fresh thread's projection; without a sample the empirical 3 chars/token default applies, and degenerate samples clamp to [0.5, 4]. Related: #125254 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN * fix(codex): make continuity calibration monotone - samples only tighten the cap Red-team finding: a loose sample (up to 4 chars/token) followed by denser content could size the cap past the empirical default, and stale or non-continuity samples persist on the binding. Clamping the calibrated ratio at the empirical default makes every such failure mode degrade to the uncalibrated behavior instead of past it, and the invariant test asserts monotonicity across poisoned samples directly. Related: #125254 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN * fix(codex): record continuity calibration only from continuity projections ClawSweeper P2: calibration ran after every successful turn filtered only by prompt size, so a dense direct or active-engine prompt could persist a sample whose density later shrinks continuity history it never measured. The no-engine continuity appliers now mark the prompt state, finalize gates the sample on that marker, and a cross-mode regression proves a large direct prompt records nothing. Related: #125254 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN --------- Co-authored-by: Marvinthebored <262704729+Marvinthebored@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>