force fresh session: ↻ new session button + /new-session
bus carries a one-shot AtomicBool armed by POST /api/new-session (or the /new-session slash command). next turn drops --continue, starting a fresh claude session; the flag clears automatically so subsequent turns resume normal behavior. /compact still always uses --continue — compacting a non-existent session is a no-op anyway. per-agent page grows an ↻ new session button next to the cancel-turn one (always visible, amber, confirms before posting since dropping --continue context isn't reversible). slash-command surface picks up /new-session for parity with the button. note row emitted on the live feed both at arm- time and again when the turn actually consumes the flag, so the operator can confirm it landed.
This commit is contained in:
parent
14aa7c7acc
commit
034b4fde10
6 changed files with 102 additions and 6 deletions
|
|
@ -82,6 +82,7 @@ pub async fn serve(
|
|||
.route("/api/cancel", post(post_cancel_turn))
|
||||
.route("/api/compact", post(post_compact))
|
||||
.route("/api/model", post(post_set_model))
|
||||
.route("/api/new-session", post(post_new_session))
|
||||
.with_state(state);
|
||||
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
||||
let listener = bind_with_retry(addr, "web UI").await?;
|
||||
|
|
@ -427,6 +428,21 @@ async fn post_compact(State(state): State<AppState>) -> Response {
|
|||
/// final result row. Emits a Note so the operator sees the cancel
|
||||
/// landed; the actual state transition back to `idle` happens when
|
||||
/// `run_claude` wakes up and the harness emits `TurnEnd`.
|
||||
/// Arm a one-shot: the next claude turn drops `--continue`, starting a
|
||||
/// fresh session. Subsequent turns resume normal `--continue`
|
||||
/// behavior. Idempotent before the next turn fires — calling twice
|
||||
/// still results in a single fresh start. Useful when the
|
||||
/// session-resume context is poisoned (claude went off the rails,
|
||||
/// hit an unrecoverable refusal, etc.) and a full reset is cheaper
|
||||
/// than asking claude to forget mid-stream.
|
||||
async fn post_new_session(State(state): State<AppState>) -> Response {
|
||||
state.bus.request_new_session();
|
||||
state.bus.emit(crate::events::LiveEvent::Note(
|
||||
"operator: new session armed — next turn runs without --continue".into(),
|
||||
));
|
||||
Redirect::to("/").into_response()
|
||||
}
|
||||
|
||||
async fn post_cancel_turn(State(state): State<AppState>) -> Response {
|
||||
let out = tokio::process::Command::new("pkill")
|
||||
.args(["-INT", "claude"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue