fix(cron): warn on context-window approach + expose session size (#3693)#4572
Merged
Conversation
…PI (#3693) cron_session_max_tokens / cron_session_max_messages already prune Persistent cron sessions before each fire (since #2989). This PR closes the operator-visibility gap that the umbrella issue #3693 flagged: - tracing::warn! when the post-prune session estimate exceeds cron_session_warn_fraction (new KernelConfig field, default 0.8) of the provider's context window. First indication of pressure is now a structured log line, not a hard provider 400. - Cron job status / detail responses now include session_message_count and session_token_count so dashboard / operators can graph growth trends. - docs/architecture/cron-session-sizing.md documents both pruning caps + the new warn fraction + the API observability fields. Two new KernelConfig fields: cron_session_warn_fraction: Option<f64> (default Some(0.8)) cron_session_warn_total_tokens: Option<u64> (default Some(200_000)) The warn-fraction is applied against cron_session_max_tokens when set, otherwise against cron_session_warn_total_tokens as a fallback ceiling so jobs that have not opted into pruning still get warnings. Two new fields on the cron job detail / status JSON response: session_message_count: u64 session_token_count: u64 Both default to 0 when no Persistent cron session exists yet. Strictly additive — existing clients keep working. Side effect of the warn wiring: the prune block now only writes the session back to disk when messages were actually drained (was: write on every fire that entered the prune branch). This avoids touching SQLite on warn-only fires. Gentle summarize-and-trim compaction (issue gap #4) is tracked separately under #3693 — it requires a synthetic LLM round-trip and is a larger change. Closes part of #3693
houko
enabled auto-merge (squash)
May 4, 2026 12:47
This was referenced May 4, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
tracing::warn!when a Persistent cron session passescron_session_warn_fraction(default 0.8) of its effective token budget — first signal of context pressure is now a structured log line, not a hard provider 400.GET /api/cron/jobs/{id}andGET /api/cron/jobs/{id}/statuswithsession_message_countandsession_token_countso dashboards / operators can graph growth trends.docs/architecture/cron-session-sizing.mddocuments the existing prune knobs (cron_session_max_tokens,cron_session_max_messages), the new warn knobs, the API observability fields, and a "pick a strategy" matrix.Why
cron_session_max_tokens/cron_session_max_messages(since #2989) already prune the persistent(agent, "cron")session before each fire. The umbrella issue #3693 flagged that operators still had no way to see growth coming: pruning prevents the 400, but only after the cap has been reached, and there is nothing to graph in the meantime. This PR fills that gap.New KernelConfig fields
cron_session_warn_fractionOption<f64>Some(0.8)tracing::warn!. Out-of-range / non-finite values silently disable the warn.cron_session_warn_total_tokensOption<u64>Some(200_000)cron_session_warn_fractionwhencron_session_max_tokensis unset. Set toNoneto require an explicit cap.Both have
#[serde(default = ...)]so older configs keep working.New API response fields
On
GET /api/cron/jobs/{id}andGET /api/cron/jobs/{id}/status:session_message_countu64(agent, "cron")session.session_token_countu64Both default to
0when the cron session does not exist yet (job has never fired, or onlysession_mode = "new"fires). Strictly additive; existing clients are unaffected.Out of scope (follow-up under #3693)
Gentle summarize-and-trim compaction (replace the dropped tail with a short LLM-generated summary instead of pure drop-from-front). That requires a synthetic LLM round-trip per fire and is a larger change. Tracked under the same umbrella issue.
Implementation notes
resolve_cron_warn_threshold(max_tokens, warn_fallback, fraction)covers all the boundary conditions (NaN / Inf / negative / zero / >1.0 / both budgets unset). Unit-tested incrates/librefang-kernel/src/kernel/tests.rs.librefang_runtime::compactor::estimate_token_count(CJK-aware char-weighted heuristic — same as the prune loop). No new tokenizer dependency.Verification
cargois forbidden from this worktree (multi-worktree contention rule fromCLAUDE.md); CI runs the full workspace build, clippy, andlibrefang-apiintegration tests including the two new tests.resolve_cron_warn_threshold_*(8 unit tests inkernel/tests.rs) — covers NaN / Inf / out-of-range fraction / zero budget / partial-token ceiling.cron_job_get_response_has_session_size_fields— boots a real kernel viaMockKernelBuilder, registers a cron job, seeds three messages into the cron session, asserts both fields present and non-zero on/api/cron/jobs/{id}and/api/cron/jobs/{id}/status.cron_job_get_response_session_fields_default_zero_when_no_session— asserts both fields are0(not absent) when no cron session exists yet.Refs #3693