recv: drop wait_seconds from the MCP tool, always an immediate peek
This commit is contained in:
parent
9e7158f593
commit
ceff662d25
6 changed files with 59 additions and 117 deletions
|
|
@ -39,33 +39,26 @@ pub fn format_ack(
|
|||
|
||||
/// Format helper for `recv`: renders zero, one, or many popped
|
||||
/// messages. Empty list collapses to "(empty)" so claude doesn't go
|
||||
/// hunting for content; when `waited` is set (the call parked on a
|
||||
/// long-poll that timed out) the empty result also carries
|
||||
/// [`IDLE_WAIT_HINT`] nudging the model toward other work. A single
|
||||
/// message renders as the historical `from: X\n\nbody` block (banner
|
||||
/// first if `redelivered`). A multi-message batch renders with a
|
||||
/// `popped N message(s):` header and `---` separators between bodies
|
||||
/// so the model can tell where one ends and the next begins;
|
||||
/// per-message redelivery banners included.
|
||||
/// hunting for content. A single message renders as the historical
|
||||
/// `from: X\n\nbody` block (banner first if `redelivered`). A
|
||||
/// multi-message batch renders with a `popped N message(s):` header
|
||||
/// and `---` separators between bodies so the model can tell where
|
||||
/// one ends and the next begins; per-message redelivery banners
|
||||
/// included.
|
||||
#[must_use]
|
||||
pub fn format_recv(
|
||||
resp: Result<hive_core_agent_sock::Response, anyhow::Error>,
|
||||
waited: bool,
|
||||
) -> String {
|
||||
pub fn format_recv(resp: Result<hive_core_agent_sock::Response, anyhow::Error>) -> String {
|
||||
match resp {
|
||||
Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages,
|
||||
remaining,
|
||||
}) => render_recv_messages(&messages, remaining, waited),
|
||||
}) => render_recv_messages(&messages, remaining),
|
||||
// A graceful stop is pending — the inbox is fenced. Render a single
|
||||
// explicit directive (not an empty inbox, which claude's "park on recv"
|
||||
// habit would long-poll again, stalling the stop-checkpoint turn until
|
||||
// the drain wait times out into a hard stop) so every recv during the
|
||||
// stop unmissably tells claude to flush + end. `remaining` is forced
|
||||
// to 0 — the inbox is fenced, so a "N more pending" hint would be
|
||||
// misleading.
|
||||
// explicit directive (not an empty inbox, which claude might just
|
||||
// recv again) so every recv during the stop unmissably tells claude
|
||||
// to flush + end. `remaining` is forced to 0 — the inbox is fenced,
|
||||
// so a "N more pending" hint would be misleading.
|
||||
Ok(hive_core_agent_sock::Response::GracefulStop) => {
|
||||
render_recv_messages(&[graceful_stop_message()], 0, waited)
|
||||
render_recv_messages(&[graceful_stop_message()], 0)
|
||||
}
|
||||
other => reply_err(other, "recv"),
|
||||
}
|
||||
|
|
@ -92,18 +85,10 @@ fn graceful_stop_message() -> hive_sh4re::DeliveredMessage {
|
|||
/// depth; when non-zero a shared "(N more pending …)" hint (identical to the
|
||||
/// wake prompt's) is appended so an in-turn drain knows more is queued. The
|
||||
/// empty path never carries the hint (nothing was popped).
|
||||
fn render_recv_messages(
|
||||
messages: &[hive_sh4re::DeliveredMessage],
|
||||
remaining: u64,
|
||||
waited: bool,
|
||||
) -> String {
|
||||
fn render_recv_messages(messages: &[hive_sh4re::DeliveredMessage], remaining: u64) -> String {
|
||||
use std::fmt::Write as _;
|
||||
if messages.is_empty() {
|
||||
return if waited {
|
||||
format!("(empty){IDLE_WAIT_HINT}")
|
||||
} else {
|
||||
"(empty)".to_owned()
|
||||
};
|
||||
return "(empty)".to_owned();
|
||||
}
|
||||
let mut out = if messages.len() == 1 {
|
||||
let m = &messages[0];
|
||||
|
|
@ -151,14 +136,6 @@ fn msg_id_tag(id: i64) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Appended to the `recv` empty result when the agent parked on a
|
||||
/// long-poll (`wait_seconds > 0`) that timed out with nothing new.
|
||||
/// Nudges the model to spend the idle time on other useful work
|
||||
/// instead of immediately re-blocking on `recv`.
|
||||
pub const IDLE_WAIT_HINT: &str = " — nothing arrived before the wait timed out. \
|
||||
If you have other useful work (assigned issues, in-flight PRs, a docs sweep, \
|
||||
notes to update), do that now rather than immediately parking on recv again.";
|
||||
|
||||
/// Inner renderer for a `Vec<LooseEnd>` already extracted from the socket
|
||||
/// reply. Called by the `get_loose_ends` handler, which injects the
|
||||
/// `UnreadMatrix` entry before formatting.
|
||||
|
|
@ -544,7 +521,7 @@ pub fn annotate_retries(mut s: String, retries: u32) -> String {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{IDLE_WAIT_HINT, format_recv};
|
||||
use super::format_recv;
|
||||
|
||||
fn msg(id: i64, from: &str, body: &str) -> hive_sh4re::DeliveredMessage {
|
||||
hive_sh4re::DeliveredMessage {
|
||||
|
|
@ -557,39 +534,20 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn empty_recv_after_wait_appends_idle_hint() {
|
||||
let out = format_recv(
|
||||
Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![],
|
||||
remaining: 0,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
assert!(out.starts_with("(empty)"));
|
||||
assert!(out.contains(IDLE_WAIT_HINT));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_recv_without_wait_has_no_hint() {
|
||||
let out = format_recv(
|
||||
Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![],
|
||||
remaining: 0,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
fn empty_recv_renders_bare_empty_marker() {
|
||||
let out = format_recv(Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![],
|
||||
remaining: 0,
|
||||
}));
|
||||
assert_eq!(out, "(empty)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_recv_with_remaining_appends_pending_hint() {
|
||||
let out = format_recv(
|
||||
Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![msg(7, "alice", "hi")],
|
||||
remaining: 3,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
let out = format_recv(Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![msg(7, "alice", "hi")],
|
||||
remaining: 3,
|
||||
}));
|
||||
assert!(out.starts_with("[msg #7] from: alice"));
|
||||
assert!(out.contains("3 more message(s) pending"));
|
||||
assert!(out.contains("max: 3"));
|
||||
|
|
@ -597,25 +555,19 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn single_recv_no_remaining_has_no_pending_hint() {
|
||||
let out = format_recv(
|
||||
Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![msg(7, "alice", "hi")],
|
||||
remaining: 0,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
let out = format_recv(Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![msg(7, "alice", "hi")],
|
||||
remaining: 0,
|
||||
}));
|
||||
assert!(!out.contains("more message(s) pending"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_recv_with_remaining_appends_pending_hint_once() {
|
||||
let out = format_recv(
|
||||
Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![msg(7, "alice", "hi"), msg(8, "bob", "yo")],
|
||||
remaining: 9,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
let out = format_recv(Ok(hive_core_agent_sock::Response::Messages {
|
||||
messages: vec![msg(7, "alice", "hi"), msg(8, "bob", "yo")],
|
||||
remaining: 9,
|
||||
}));
|
||||
assert!(out.starts_with("popped 2 message(s):"));
|
||||
assert_eq!(out.matches("more message(s) pending").count(), 1);
|
||||
// `max` suggestion is clamped to the server-side recv cap.
|
||||
|
|
|
|||
Loading…
Reference in a new issue