hive-agent: a failed turn-end /compact keeps the turn's own compacted flag
The turn-end path returned the /compact's success as the turn's outcome, so a turn that had already compacted (reactively or per policy) was recorded as not compacted when its queued /compact then failed. The outcome now folds the two with `||`, via `with_turn_end_compact`, which the tests pin.
This commit is contained in:
parent
7bb1959a94
commit
2c4a3c2fa7
1 changed files with 26 additions and 3 deletions
|
|
@ -461,7 +461,7 @@ pub async fn drive_turn(
|
||||||
// Reflect `Compacting` in the UI like the idle path (`run_pending_compact`)
|
// Reflect `Compacting` in the UI like the idle path (`run_pending_compact`)
|
||||||
// does; the serve loop resets to `Idle` once this turn returns.
|
// does; the serve loop resets to `Idle` once this turn returns.
|
||||||
bus.set_state(crate::events::TurnState::Compacting);
|
bus.set_state(crate::events::TurnState::Compacting);
|
||||||
let compacted = report_compact(bus, session.compact(&config, &sink).await);
|
let compact_ok = report_compact(bus, session.compact(&config, &sink).await);
|
||||||
// If the compact call asked to be woken (the agent's own `compact`
|
// If the compact call asked to be woken (the agent's own `compact`
|
||||||
// tool with a `wake_prompt`), stash it — the serve loop reads it
|
// tool with a `wake_prompt`), stash it — the serve loop reads it
|
||||||
// back after this turn returns and drives a synthetic follow-up
|
// back after this turn returns and drives a synthetic follow-up
|
||||||
|
|
@ -470,7 +470,7 @@ pub async fn drive_turn(
|
||||||
if let Some(prompt) = request.wake_prompt {
|
if let Some(prompt) = request.wake_prompt {
|
||||||
bus.set_post_compact_wake(prompt);
|
bus.set_post_compact_wake(prompt);
|
||||||
}
|
}
|
||||||
return Ok(compacted);
|
return with_turn_end_compact(outcome, compact_ok);
|
||||||
}
|
}
|
||||||
outcome
|
outcome
|
||||||
}
|
}
|
||||||
|
|
@ -495,6 +495,13 @@ fn report_compact<E: std::fmt::Display>(bus: &Bus, result: Result<(), E>) -> boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fold a turn-end `/compact` into the turn's own outcome. A compaction that
|
||||||
|
/// ran during the turn (`Ok(true)`) stays recorded even when the turn-end
|
||||||
|
/// `/compact` failed; a failed `/compact` never turns it into `Ok(false)`.
|
||||||
|
fn with_turn_end_compact(outcome: TurnOutcome, compact_ok: bool) -> TurnOutcome {
|
||||||
|
outcome.map(|turn_compacted| turn_compacted || compact_ok)
|
||||||
|
}
|
||||||
|
|
||||||
/// Pre-turn auto-reset check. If context is large AND the prompt cache has
|
/// Pre-turn auto-reset check. If context is large AND the prompt cache has
|
||||||
/// gone cold (idle time >= cache TTL), archive the current session so the
|
/// gone cold (idle time >= cache TTL), archive the current session so the
|
||||||
/// next wake-up turn's `--resume <title>` misses and self-heals into a fresh
|
/// next wake-up turn's `--resume <title>` misses and self-heals into a fresh
|
||||||
|
|
@ -835,7 +842,7 @@ fn archive_session(bus: &Bus, session: &AgentSession) {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{
|
use super::{
|
||||||
PermissionAsk, TurnError, acp_permits, nonzero_or, parse_u64, report_compact,
|
PermissionAsk, TurnError, acp_permits, nonzero_or, parse_u64, report_compact,
|
||||||
runtime_error_to_turn,
|
runtime_error_to_turn, with_turn_end_compact,
|
||||||
};
|
};
|
||||||
use crate::events::{Bus, LiveEvent};
|
use crate::events::{Bus, LiveEvent};
|
||||||
use hive_runtime::{AcpError, Error};
|
use hive_runtime::{AcpError, Error};
|
||||||
|
|
@ -1001,4 +1008,20 @@ mod tests {
|
||||||
assert!(compacted);
|
assert!(compacted);
|
||||||
assert_eq!(notes, ["/compact done"]);
|
assert_eq!(notes, ["/compact done"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_failed_turn_end_compact_keeps_the_turns_own_compaction() {
|
||||||
|
assert!(matches!(with_turn_end_compact(Ok(true), false), Ok(true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_failed_turn_end_compact_leaves_a_plain_turn_uncompacted() {
|
||||||
|
assert!(matches!(with_turn_end_compact(Ok(false), false), Ok(false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_successful_turn_end_compact_marks_the_turn_compacted() {
|
||||||
|
assert!(matches!(with_turn_end_compact(Ok(false), true), Ok(true)));
|
||||||
|
assert!(matches!(with_turn_end_compact(Ok(true), true), Ok(true)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue