fix(agent): pin claude session by constant title, archive on reset
This commit is contained in:
parent
6528a90233
commit
e35acca814
4 changed files with 369 additions and 164 deletions
|
|
@ -680,21 +680,24 @@ pub struct Bus {
|
|||
/// `container_view` can surface the status on the dashboard without
|
||||
/// a live socket call.
|
||||
rate_limited: Arc<AtomicBool>,
|
||||
/// One-shot: next `run_claude` call drops `--continue`, starting
|
||||
/// a fresh claude session. Set by `POST /api/new-session` from
|
||||
/// the per-agent web UI; consumed (cleared back to false) by the
|
||||
/// next turn. Subsequent turns resume normal `--continue`
|
||||
/// behavior. Atomic so the consumer can take-and-clear without a
|
||||
/// lock.
|
||||
skip_continue_once: Arc<AtomicBool>,
|
||||
/// One-shot: operator asked to reset the claude session (`POST
|
||||
/// /api/new-session`). Consumed at the *next* turn boundary by
|
||||
/// `turn::drive_turn`, which archives the current session so the turn
|
||||
/// starts fresh. Deferred (not applied in the handler) so the archive
|
||||
/// never races a claude process mid-write — one claude per container,
|
||||
/// serialized by the serve loop, so the turn boundary is the only point
|
||||
/// where no session file is open.
|
||||
session_reset_pending: Arc<AtomicBool>,
|
||||
/// Current fresh-claude-session id (FK to `sessions.id`). Set by the
|
||||
/// bin loop after minting a session row on a fresh start; stamped onto
|
||||
/// every `turn_stats` row until the next fresh session. `None` before
|
||||
/// the first fresh turn or when the stats db is unavailable.
|
||||
session_id: Arc<Mutex<Option<i64>>>,
|
||||
/// One-shot: `run_claude` flips this true when it suppresses
|
||||
/// `--continue` (a fresh session). The bin loop takes-and-clears it
|
||||
/// after the turn to decide whether to mint a new `sessions` row.
|
||||
/// One-shot: `run_claude` flips this true when it creates a fresh claude
|
||||
/// session (`--name <title>` on a title miss). The bin loop takes-and-
|
||||
/// clears it after the turn to decide whether to mint a new `sessions`
|
||||
/// row. Session identity itself is handled entirely in `turn.rs` via the
|
||||
/// constant title + archive — this flag is purely a stats signal.
|
||||
fresh_session: Arc<AtomicBool>,
|
||||
/// Per-turn tool-call counter. Reset by the bin loop between
|
||||
/// turns via `take_tool_calls`. Populated by `observe_stream` as
|
||||
|
|
@ -773,7 +776,7 @@ impl Bus {
|
|||
last_ctx_usage: Arc::new(Mutex::new(None)),
|
||||
last_cost_usage: Arc::new(Mutex::new(None)),
|
||||
rate_limited: Arc::new(AtomicBool::new(was_rate_limited)),
|
||||
skip_continue_once: Arc::new(AtomicBool::new(false)),
|
||||
session_reset_pending: Arc::new(AtomicBool::new(false)),
|
||||
session_id: Arc::new(Mutex::new(None)),
|
||||
fresh_session: Arc::new(AtomicBool::new(false)),
|
||||
tool_calls: Arc::new(Mutex::new(std::collections::HashMap::new())),
|
||||
|
|
@ -797,23 +800,24 @@ impl Bus {
|
|||
self.event_seq.fetch_add(1, Ordering::SeqCst) + 1
|
||||
}
|
||||
|
||||
/// Arm the one-shot: the next claude invocation will run without
|
||||
/// `--continue`, dropping any prior session context. Idempotent
|
||||
/// — calling twice in a row before the next turn still consumes
|
||||
/// to a single fresh-start.
|
||||
pub fn request_new_session(&self) {
|
||||
self.skip_continue_once.store(true, Ordering::SeqCst);
|
||||
/// Request a session reset (operator `POST /api/new-session`). Deferred:
|
||||
/// the flag is consumed at the next turn boundary by `drive_turn`, which
|
||||
/// archives the current session so no claude process is mid-write when the
|
||||
/// file is renamed. Idempotent — two clicks before the next turn still
|
||||
/// archive once.
|
||||
pub fn request_session_reset(&self) {
|
||||
self.session_reset_pending.store(true, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
/// Take + clear the one-shot. Returns true iff the caller should
|
||||
/// run claude without `--continue` for this turn.
|
||||
/// Take + clear the session-reset one-shot. Returns true iff `drive_turn`
|
||||
/// should archive the current session before this turn.
|
||||
#[must_use]
|
||||
pub fn take_skip_continue(&self) -> bool {
|
||||
self.skip_continue_once.swap(false, Ordering::SeqCst)
|
||||
pub fn take_session_reset(&self) -> bool {
|
||||
self.session_reset_pending.swap(false, Ordering::SeqCst)
|
||||
}
|
||||
|
||||
/// Mark that the current turn started a fresh claude session.
|
||||
/// `run_claude` calls this when it suppresses `--continue`.
|
||||
/// `run_claude` calls this when it creates a new titled session.
|
||||
pub fn mark_fresh_session(&self) {
|
||||
self.fresh_session.store(true, Ordering::SeqCst);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue