Sweep every first-party crate source (1956 .rs files) to the project comment guidelines: delete redundant restatements, decorative banners, change narration, and end-of-line comments; keep and tighten the crucial ones (invariants, bug rationale, SAFETY blocks, ported-source attribution). No functional code changed. Every edit is proven comment-only against the prior tree by a comment-stripping lexer (string/char/raw-string aware) plus a separate doctest-fence check. Where removing a comment made rustfmt or clippy want to re-lay-out adjacent code, the minimal triggering comment is restored so code tokens stay byte-identical. Gates green: cargo fmt --all --check (0 diffs), cargo check and cargo clippy --workspace --all-targets (0 warnings). Adds scripts/check_codegen_comment_guidelines.py — the enforcement gate for these guidelines (flags banners, end-of-line comments, change narration, and commented-out code).
147 lines
6.2 KiB
Rust
147 lines
6.2 KiB
Rust
/// Default auto-compact threshold (% of context window) when no source sets it.
|
|
pub const DEFAULT_AUTO_COMPACT_THRESHOLD_PERCENT: u8 = 85;
|
|
|
|
/// Env-var override for `auto_compact_threshold_percent`. Parsed as `u8`;
|
|
/// out-of-range or unparseable values are ignored.
|
|
pub(crate) const ENV_AUTO_COMPACT_THRESHOLD_PERCENT: &str = "KIGI_AUTO_COMPACT_THRESHOLD_PERCENT";
|
|
|
|
/// Resolve auto-compact threshold percent (0-100) for the given model.
|
|
///
|
|
/// Two scopes (per-model and global) across two tiers (user TOML and
|
|
/// remote settings). User-tier always wins over remote; within a tier, per-model
|
|
/// wins over global. Env var sits on top as a per-process override.
|
|
///
|
|
/// Precedence (highest first):
|
|
/// 1. env `KIGI_AUTO_COMPACT_THRESHOLD_PERCENT`
|
|
/// 2. user TOML `[model.<id>].auto_compact_threshold_percent`
|
|
/// (read from `cfg.config_models`; the effective merge of user +
|
|
/// managed `[model.<id>]` sections)
|
|
/// 3. user TOML `[session].auto_compact_threshold_percent`
|
|
/// (read from `cfg.session.auto_compact_threshold_percent: Option<u8>`)
|
|
/// 4. remote settings per-model `ModelInfo.auto_compact_threshold_percent`
|
|
/// (populated from `kigi_models[i].auto_compact_threshold_percent`;
|
|
/// intentionally NOT collapsed via `ConfigModelOverride::apply` so the
|
|
/// user-vs-GB per-model distinction is preserved)
|
|
/// 5. remote settings global `RemoteSettings.auto_compact_threshold_percent`
|
|
/// (populated from `kigi_settings.auto_compact_threshold_percent`)
|
|
/// 6. default `DEFAULT_AUTO_COMPACT_THRESHOLD_PERCENT` (85)
|
|
///
|
|
/// Values outside `0..=100` from the env var are ignored with a debug log and
|
|
/// the resolver falls through to the next tier. TOML/remote fields are typed
|
|
/// `u8` and so naturally constrained.
|
|
pub fn resolve_auto_compact_threshold_percent(
|
|
cfg: &crate::agent::config::Config,
|
|
model_id: &str,
|
|
model: Option<&crate::agent::config::ModelInfo>,
|
|
) -> u8 {
|
|
resolve_auto_compact_threshold_percent_from_tiers(
|
|
cfg.config_models
|
|
.get(model_id)
|
|
.and_then(|m| m.auto_compact_threshold_percent),
|
|
cfg.session.auto_compact_threshold_percent,
|
|
model.and_then(|m| m.auto_compact_threshold_percent),
|
|
cfg.remote_settings
|
|
.as_ref()
|
|
.and_then(|r| r.auto_compact_threshold_percent),
|
|
)
|
|
}
|
|
|
|
/// Lower-level form of [`resolve_auto_compact_threshold_percent`] that takes
|
|
/// the four tiers as plain `Option<u8>` values rather than reaching into a
|
|
/// `Config`. Useful from sites that don't hold a `Config` reference (e.g.,
|
|
/// subagent spawn paths where the parent's config tiers are plumbed in
|
|
/// explicitly and the per-model lookup uses the SUBAGENT's resolved model id,
|
|
/// not the parent's).
|
|
///
|
|
/// Precedence: env > `user_per_model` > `user_global` > `gb_per_model`
|
|
/// > `gb_global` > `DEFAULT_AUTO_COMPACT_THRESHOLD_PERCENT`.
|
|
pub fn resolve_auto_compact_threshold_percent_from_tiers(
|
|
user_per_model: Option<u8>,
|
|
user_global: Option<u8>,
|
|
gb_per_model: Option<u8>,
|
|
gb_global: Option<u8>,
|
|
) -> u8 {
|
|
fn clamp_env(raw: i64) -> Option<u8> {
|
|
if (0..=100).contains(&raw) {
|
|
Some(raw as u8)
|
|
} else {
|
|
tracing::debug!(
|
|
source = "env",
|
|
value = raw,
|
|
"auto_compact_threshold_percent out of range 0..=100; ignoring"
|
|
);
|
|
None
|
|
}
|
|
}
|
|
let from_env = || -> Option<u8> {
|
|
std::env::var(ENV_AUTO_COMPACT_THRESHOLD_PERCENT)
|
|
.ok()
|
|
.and_then(|s| s.parse::<i64>().ok())
|
|
.and_then(clamp_env)
|
|
};
|
|
|
|
from_env()
|
|
.or(user_per_model)
|
|
.or(user_global)
|
|
.or(gb_per_model)
|
|
.or(gb_global)
|
|
.unwrap_or(DEFAULT_AUTO_COMPACT_THRESHOLD_PERCENT)
|
|
}
|
|
|
|
/// Client default per-compaction wall-clock budget (seconds). Fleet p99 of
|
|
/// successful compactions is ~181s (≈225s at 400K+ input), so 300s clears the
|
|
/// legit tail with margin while cutting a runaway from the ~600s deadline.
|
|
pub const DEFAULT_COMPACTION_WALL_CLOCK_BUDGET_SECS: u64 = 300;
|
|
|
|
/// Below this, a configured budget is almost certainly a misconfig (fleet
|
|
/// success p99 ~181s); logged at `warn`, not clamped.
|
|
const COMPACTION_WALL_CLOCK_BUDGET_WARN_SECS: u64 = 120;
|
|
|
|
/// Env override for the compaction wall-clock budget (seconds). Parsed as
|
|
/// `u64`; unparseable values fall through.
|
|
const ENV_COMPACTION_WALL_CLOCK_BUDGET_SECS: &str = "KIGI_COMPACTION_WALL_CLOCK_SECS";
|
|
|
|
/// Resolve the per-compaction wall-clock budget (seconds). Precedence: env
|
|
/// `KIGI_COMPACTION_WALL_CLOCK_SECS` > remote settings global
|
|
/// `RemoteSettings.compaction_wall_clock_budget_secs` >
|
|
/// [`DEFAULT_COMPACTION_WALL_CLOCK_BUDGET_SECS`] (a per-model `ModelInfo` tier
|
|
/// would slot in ahead of the global one).
|
|
///
|
|
/// `0` **disables** it. Low values are warned, not clamped — any "safe" clamp
|
|
/// (e.g. 30s) would itself cut legit compactions, trading one silent failure for
|
|
/// another; ops own the value.
|
|
pub fn resolve_compaction_wall_clock_budget_secs(gb_global: Option<u64>) -> u64 {
|
|
let from_env = std::env::var(ENV_COMPACTION_WALL_CLOCK_BUDGET_SECS)
|
|
.ok()
|
|
.and_then(|s| s.trim().parse::<u64>().ok());
|
|
let resolved = from_env
|
|
.or(gb_global)
|
|
.unwrap_or(DEFAULT_COMPACTION_WALL_CLOCK_BUDGET_SECS);
|
|
if resolved > 0 && resolved < COMPACTION_WALL_CLOCK_BUDGET_WARN_SECS {
|
|
tracing::warn!(
|
|
budget_secs = resolved,
|
|
"compaction wall-clock budget {resolved}s is below {COMPACTION_WALL_CLOCK_BUDGET_WARN_SECS}s \
|
|
and may cut legitimate compactions (fleet success p99 ~181s); set 0 to disable"
|
|
);
|
|
}
|
|
resolved
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod compaction_wall_clock_budget_tests {
|
|
use super::resolve_compaction_wall_clock_budget_secs as resolve;
|
|
|
|
// Assumes KIGI_COMPACTION_WALL_CLOCK_SECS is unset in the test env.
|
|
#[test]
|
|
fn default_global_disable_and_no_clamp() {
|
|
// client default
|
|
assert_eq!(resolve(None), 300);
|
|
// server global wins
|
|
assert_eq!(resolve(Some(450)), 450);
|
|
// 0 explicitly disables (no clamp)
|
|
assert_eq!(resolve(Some(0)), 0);
|
|
// low values pass through (warned, not clamped)
|
|
assert_eq!(resolve(Some(5)), 5);
|
|
}
|
|
}
|