hive-agent: surface an interrupted-turn banner in the wake prompt after /cancel
This commit is contained in:
parent
9f5ce4d941
commit
a11f945532
5 changed files with 72 additions and 6 deletions
|
|
@ -54,7 +54,17 @@ pub(super) async fn post_send(
|
|||
pub(super) async fn post_cancel_turn(State(state): State<AppState>) -> Response {
|
||||
let out = super::sigint_claude().await;
|
||||
let note = match out {
|
||||
Ok(o) if o.status.success() => "operator: /cancel — sent SIGINT to claude".to_owned(),
|
||||
Ok(o) if o.status.success() => {
|
||||
// A process actually got signalled — the *next* turn's wake
|
||||
// prompt should tell the agent it was cut off mid-work. Only
|
||||
// set on an actual signal: a `pkill` exit 1 ("no process to
|
||||
// interrupt") means /cancel raced an already-finished turn, so
|
||||
// there's nothing to flag as interrupted.
|
||||
state
|
||||
.interrupted
|
||||
.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
"operator: /cancel — sent SIGINT to claude".to_owned()
|
||||
}
|
||||
Ok(o) if o.status.code() == Some(1) => {
|
||||
"operator: /cancel — no claude process to interrupt".to_owned()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ mod stream;
|
|||
|
||||
use std::net::SocketAddr;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
|
@ -57,6 +58,13 @@ struct AppState {
|
|||
/// VNC port from the `HIVE_GUI_VNC_PORT` env var at startup.
|
||||
/// `None` when unset (gui not enabled for this agent).
|
||||
gui_vnc_port: Option<u16>,
|
||||
/// Set by `post_cancel_turn` on a successful SIGINT; read-and-cleared
|
||||
/// by the serve loop's next `handle_turn` to prepend
|
||||
/// `hive_sh4re::INTERRUPTED_HINT` to that turn's wake prompt. Shared
|
||||
/// with the serve loop via the same `Arc` (see `serve_main`) — an
|
||||
/// in-memory flag, not a marker file, since a `/cancel` from a prior
|
||||
/// process lifetime isn't meaningful once the harness restarts.
|
||||
interrupted: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
/// Bind the per-container web listener and serve the SPA.
|
||||
|
|
@ -77,6 +85,7 @@ pub async fn serve(
|
|||
login: LoginStateCell,
|
||||
bus: Bus,
|
||||
socket: PathBuf,
|
||||
interrupted: Arc<AtomicBool>,
|
||||
) -> Result<()> {
|
||||
let gui_vnc_port = read_gui_vnc_port();
|
||||
let static_dir: PathBuf = std::env::var_os("HIVE_STATIC_DIR")
|
||||
|
|
@ -99,6 +108,7 @@ pub async fn serve(
|
|||
bus,
|
||||
socket,
|
||||
gui_vnc_port,
|
||||
interrupted,
|
||||
};
|
||||
let app: Router<AppState> = Router::new()
|
||||
.route("/api/state", get(state::api_state))
|
||||
|
|
|
|||
Loading…
Reference in a new issue