idle: afk command, configurable session timeout, fix block_reason
Add `poc-daemon afk` to immediately mark Kent as away, allowing the idle timer to fire without waiting for the session active timeout. Add `poc-daemon session-timeout <secs>` to configure how long after the last message Kent counts as "present" (default 15min, persisted). Fix block_reason() to report "kent present" and "in turn" states that were checked in the tick but not in the diagnostic output.
This commit is contained in:
parent
05e0f1d5be
commit
55fdc3dad7
4 changed files with 66 additions and 2 deletions
|
|
@ -15,7 +15,7 @@ use tracing::info;
|
|||
// Defaults
|
||||
const DEFAULT_IDLE_TIMEOUT: f64 = 5.0 * 60.0;
|
||||
const DEFAULT_NOTIFY_TIMEOUT: f64 = 2.0 * 60.0;
|
||||
const SESSION_ACTIVE_SECS: f64 = 15.0 * 60.0;
|
||||
const DEFAULT_SESSION_ACTIVE_SECS: f64 = 15.0 * 60.0;
|
||||
const DREAM_INTERVAL_HOURS: u64 = 18;
|
||||
|
||||
/// EWMA decay half-life in seconds (5 minutes).
|
||||
|
|
@ -52,6 +52,8 @@ struct Persisted {
|
|||
#[serde(default)]
|
||||
ewma_updated_at: f64,
|
||||
#[serde(default)]
|
||||
session_active_secs: f64,
|
||||
#[serde(default)]
|
||||
in_turn: bool,
|
||||
#[serde(default)]
|
||||
turn_start: f64,
|
||||
|
|
@ -110,6 +112,7 @@ pub struct State {
|
|||
pub notify_timeout: f64,
|
||||
pub activity_ewma: f64,
|
||||
pub ewma_updated_at: f64,
|
||||
pub session_active_secs: f64,
|
||||
pub in_turn: bool,
|
||||
pub turn_start: f64,
|
||||
pub last_nudge: f64,
|
||||
|
|
@ -135,6 +138,7 @@ impl State {
|
|||
fired: false,
|
||||
idle_timeout: DEFAULT_IDLE_TIMEOUT,
|
||||
notify_timeout: DEFAULT_NOTIFY_TIMEOUT,
|
||||
session_active_secs: DEFAULT_SESSION_ACTIVE_SECS,
|
||||
activity_ewma: 0.0,
|
||||
ewma_updated_at: now(),
|
||||
in_turn: false,
|
||||
|
|
@ -157,6 +161,9 @@ impl State {
|
|||
if p.notify_timeout > 0.0 {
|
||||
self.notify_timeout = p.notify_timeout;
|
||||
}
|
||||
if p.session_active_secs > 0.0 {
|
||||
self.session_active_secs = p.session_active_secs;
|
||||
}
|
||||
// Reset activity timestamps to now — timers count from
|
||||
// restart, not from stale pre-restart state
|
||||
let t = now();
|
||||
|
|
@ -197,6 +204,7 @@ impl State {
|
|||
fired: self.fired,
|
||||
idle_timeout: self.idle_timeout,
|
||||
notify_timeout: self.notify_timeout,
|
||||
session_active_secs: self.session_active_secs,
|
||||
activity_ewma: self.activity_ewma,
|
||||
ewma_updated_at: self.ewma_updated_at,
|
||||
in_turn: self.in_turn,
|
||||
|
|
@ -284,6 +292,20 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn handle_afk(&mut self) {
|
||||
// Push last_user_msg far enough back that kent_present() returns false
|
||||
self.last_user_msg = now() - self.session_active_secs - 1.0;
|
||||
self.fired = false; // allow idle timer to fire again
|
||||
info!("Kent marked AFK");
|
||||
self.save();
|
||||
}
|
||||
|
||||
pub fn handle_session_timeout(&mut self, secs: f64) {
|
||||
self.session_active_secs = secs;
|
||||
info!("session active timeout = {secs}s");
|
||||
self.save();
|
||||
}
|
||||
|
||||
pub fn handle_idle_timeout(&mut self, secs: f64) {
|
||||
self.idle_timeout = secs;
|
||||
self.save();
|
||||
|
|
@ -331,7 +353,7 @@ impl State {
|
|||
}
|
||||
|
||||
pub fn kent_present(&self) -> bool {
|
||||
(now() - self.last_user_msg) < SESSION_ACTIVE_SECS
|
||||
(now() - self.last_user_msg) < self.session_active_secs
|
||||
}
|
||||
|
||||
/// Seconds since the most recent of user message or response.
|
||||
|
|
@ -353,6 +375,10 @@ impl State {
|
|||
"consolidating"
|
||||
} else if self.dreaming {
|
||||
"dreaming"
|
||||
} else if self.kent_present() {
|
||||
"kent present"
|
||||
} else if self.in_turn {
|
||||
"in turn"
|
||||
} else if self.last_response.max(self.last_user_msg) == 0.0 {
|
||||
"no activity yet"
|
||||
} else if self.since_activity() < self.idle_timeout {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue