Synced from monorepo

Synced from monorepo

Changes:
- Release a shell session's resources in one drop
- Make the tools blocking-wait cap client-configurable and self-describing
- Recognize API "exceeds budget" errors as context overflow
- Retry /btw on model overload
- Carry running background tasks and subagents across compaction
- Require round-trip time for SDK liveness checks
- Background-subagent completion reminders with a selectable delivery surface
- Make a PTY shell reap itself until it reaches the registry
- Recover the OS error code from a TLS-phase connection reset
- Consume the attached-client signal and report why idle is withheld
- Treat `.grok/sandbox.toml` edits as protected so auto mode prompts before writing
- Surface history/search in the Ctrl+. cheatsheet and keep it working in history view
- Delete sessions from the dashboard and welcome list
- Release a session's activity record when the session ends
- Stop charging auth-retry budget for fail-closed 401s; reset it across suspends
- Scope skills watches on project vendor roots
- Make [stop] cancel in-flight compaction
- Make the leader soak measure the leader, not its harness

Source-Revision: 8d69c91f02bcacf01e98d5aebbf2f92547c45738
This commit is contained in:
grokkybara[bot] 2026-07-31 18:08:03 +00:00
commit a422116582
165 changed files with 15161 additions and 1969 deletions

File diff suppressed because it is too large Load diff

View file

@ -3076,7 +3076,9 @@ mod tests {
"supported_protocol_versions": ["1.0.0"],
});
let _ = socket.send(Message::Text(ack.to_string().into())).await;
while let Some(Ok(Message::Text(text))) = socket.recv().await {
// Ignore WS Ping/Pong/Close: keepalive fires immediately after hello.
while let Some(Ok(msg)) = socket.recv().await {
let Message::Text(text) = msg else { continue };
let Ok(value) = serde_json::from_str::<Value>(text.as_ref()) else {
continue;
};

View file

@ -433,6 +433,11 @@ mod inner {
HEARTBEAT_PONG_DROPPED_TOTAL.inc();
}
#[cfg(test)]
pub(crate) fn heartbeat_pong_dropped_count() -> u64 {
HEARTBEAT_PONG_DROPPED_TOTAL.get()
}
pub(crate) fn cancel_applied() {
CANCEL_APPLIED_TOTAL.inc();
}
@ -561,6 +566,10 @@ mod inner {
#[cfg(not(feature = "metrics"))]
mod inner {
#[cfg(test)]
static TEST_HEARTBEAT_PONG_DROPPED: std::sync::atomic::AtomicU64 =
std::sync::atomic::AtomicU64::new(0);
pub(crate) fn pool_connections_inc() {}
pub(crate) fn pool_connections_dec() {}
pub(crate) fn pool_evictions_inc() {}
@ -584,7 +593,15 @@ mod inner {
pub(crate) fn writer_sink_send_error() {}
pub(crate) fn reconnect_writer_resume() {}
pub(crate) fn liveness_deadline_expired() {}
pub(crate) fn heartbeat_pong_dropped() {}
pub(crate) fn heartbeat_pong_dropped() {
#[cfg(test)]
TEST_HEARTBEAT_PONG_DROPPED.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
#[cfg(test)]
pub(crate) fn heartbeat_pong_dropped_count() -> u64 {
TEST_HEARTBEAT_PONG_DROPPED.load(std::sync::atomic::Ordering::Relaxed)
}
pub(crate) fn cancel_applied() {}
pub(crate) fn cancel_pending_tombstoned() {}
pub(crate) fn cancel_no_target() {}
@ -619,6 +636,8 @@ pub(crate) use inner::demux_inbox_depth_set;
pub(crate) use inner::disconnect_detail_class;
pub(crate) use inner::early_notif_buffered;
pub(crate) use inner::heartbeat_pong_dropped;
#[cfg(test)]
pub(crate) use inner::heartbeat_pong_dropped_count;
pub(crate) use inner::hook_send;
pub(crate) use inner::inbox_full_notification_dropped;
pub(crate) use inner::inbox_full_reject_send_failed;

View file

@ -294,18 +294,15 @@ impl ToolServerBuilder {
}
/// Override the inbound-liveness deadline on a freshly-opened
/// connection: if no inbound WebSocket frame of any kind arrives within
/// this window, the connection is declared dead and reconnected. This
/// catches silently dead transports (e.g. a VM snapshot restore or
/// NAT/LB flow expiry) that a send-only keepalive never notices.
/// connection: if no RTT proof (WS/app pong) arrives within this
/// window, the connection is declared dead and reconnected.
/// Hub→client pings and one-way data do not re-arm.
///
/// Default (also used for a zero value): 2.5× the effective ping
/// interval — 75s at the default 30s ping — which guarantees at least
/// two keepalive pings fit in every window, so a healthy-but-idle
/// connection (one pong per ping) can never trip it. Explicit values
/// are honored verbatim; keep them comfortably above the ping interval
/// for the same reason (a value at or below the ping interval churns
/// healthy idle connections and is logged as a warning at connect).
/// Default (also used for a zero value): `min(4× ping, 120s)` — 120s
/// at the default 30s ping, still under the hub's ~150s idle. Explicit
/// values are honored verbatim; keep them comfortably above the ping
/// interval (a value at or below the ping interval churns healthy idle
/// connections and is logged as a warning at connect).
pub fn with_ws_liveness_deadline(mut self, deadline: std::time::Duration) -> Self {
self.ws_liveness_deadline = Some(deadline);
self
@ -398,8 +395,9 @@ impl ToolServerBuilder {
self
}
/// Optional callback fired once on the initial successful connect, before
/// the actor starts (so it happens-before any disconnect/reconnect).
/// Optional callback fired once on the initial successful connect, after
/// the writer task enters its loop and before the reader actor starts.
/// The first keepalive may still be in flight.
pub fn on_connect<F>(mut self, cb: F) -> Self
where
F: Fn() + Send + Sync + 'static,