refactor(#2569): rename hive-agent-sock to hive-core-agent-sock

This commit is contained in:
damocles 2026-07-20 21:58:28 +02:00
commit 795dd882bb
26 changed files with 184 additions and 161 deletions

26
Cargo.lock generated
View file

@ -1523,8 +1523,8 @@ dependencies = [
"clap", "clap",
"forgejo-api", "forgejo-api",
"futures-util", "futures-util",
"hive-agent-sock",
"hive-claude", "hive-claude",
"hive-core-agent-sock",
"hive-sh4re", "hive-sh4re",
"http-body-util", "http-body-util",
"hyper", "hyper",
@ -1552,7 +1552,7 @@ dependencies = [
"anyhow", "anyhow",
"axum", "axum",
"clap", "clap",
"hive-agent-sock", "hive-core-agent-sock",
"hive-sh4re", "hive-sh4re",
"rmcp", "rmcp",
"serde", "serde",
@ -1562,21 +1562,13 @@ dependencies = [
"tracing-subscriber", "tracing-subscriber",
] ]
[[package]]
name = "hive-agent-sock"
version = "0.1.0"
dependencies = [
"hive-sh4re",
"serde",
]
[[package]] [[package]]
name = "hive-agent-wake" name = "hive-agent-wake"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"hive-agent-sock", "hive-core-agent-sock",
"serde", "serde",
"serde_json", "serde_json",
"tokio", "tokio",
@ -1589,7 +1581,7 @@ name = "hive-bash-mcp"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hive-agent-sock", "hive-core-agent-sock",
"hive-sh4re", "hive-sh4re",
"libc", "libc",
"rmcp", "rmcp",
@ -1615,7 +1607,7 @@ dependencies = [
"clap-markdown", "clap-markdown",
"clap_complete", "clap_complete",
"forgejo-api", "forgejo-api",
"hive-agent-sock", "hive-core-agent-sock",
"hive-host-sock", "hive-host-sock",
"hive-priv-sock", "hive-priv-sock",
"hive-sh4re", "hive-sh4re",
@ -1653,6 +1645,14 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "hive-core-agent-sock"
version = "0.1.0"
dependencies = [
"hive-sh4re",
"serde",
]
[[package]] [[package]]
name = "hive-forge" name = "hive-forge"
version = "0.1.0" version = "0.1.0"

View file

@ -3,7 +3,7 @@ resolver = "3"
members = [ members = [
"hive-agent", "hive-agent",
"hive-agent-mcp", "hive-agent-mcp",
"hive-agent-sock", "hive-core-agent-sock",
"hive-agent-wake", "hive-agent-wake",
"hive-bash-mcp", "hive-bash-mcp",
"hive-c0re", "hive-c0re",
@ -51,7 +51,7 @@ clap = { version = "4", features = ["derive"] }
clap_complete = "4" clap_complete = "4"
indicatif = "0.18" indicatif = "0.18"
hive-sh4re = { path = "hive-sh4re" } hive-sh4re = { path = "hive-sh4re" }
hive-agent-sock = { path = "hive-agent-sock" } hive-core-agent-sock = { path = "hive-core-agent-sock" }
hive-claude = { path = "hive-claude" } hive-claude = { path = "hive-claude" }
hive-host-sock = { path = "hive-host-sock" } hive-host-sock = { path = "hive-host-sock" }
hive-priv-sock = { path = "hive-priv-sock" } hive-priv-sock = { path = "hive-priv-sock" }

View file

@ -14,7 +14,7 @@ workspace = true
anyhow.workspace = true anyhow.workspace = true
axum.workspace = true axum.workspace = true
clap.workspace = true clap.workspace = true
hive-agent-sock.workspace = true hive-core-agent-sock.workspace = true
hive-sh4re.workspace = true hive-sh4re.workspace = true
rmcp.workspace = true rmcp.workspace = true
serde.workspace = true serde.workspace = true

View file

@ -121,9 +121,10 @@ impl AgentServer {
/// covers both. /// covers both.
async fn dispatch( async fn dispatch(
&self, &self,
req: hive_agent_sock::Request, req: hive_core_agent_sock::Request,
) -> (Result<hive_agent_sock::Response, anyhow::Error>, u32) { ) -> (Result<hive_core_agent_sock::Response, anyhow::Error>, u32) {
match client::request_retried::<_, hive_agent_sock::Response>(&self.socket, &req).await { match client::request_retried::<_, hive_core_agent_sock::Response>(&self.socket, &req).await
{
Ok((r, n)) => (Ok(r), n), Ok((r, n)) => (Ok(r), n),
Err(e) => (Err(e), 0), Err(e) => (Err(e), 0),
} }
@ -150,7 +151,7 @@ impl AgentServer {
} }
run_tool_envelope("send", log, async move { run_tool_envelope("send", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Send { .dispatch(hive_core_agent_sock::Request::Send {
to: args.to, to: args.to,
body: args.body, body: args.body,
in_reply_to: args.in_reply_to, in_reply_to: args.in_reply_to,
@ -181,7 +182,7 @@ impl AgentServer {
let log = format!("{args:?}"); let log = format!("{args:?}");
run_tool_envelope("ask", log, async move { run_tool_envelope("ask", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Ask { .dispatch(hive_core_agent_sock::Request::Ask {
question: args.question, question: args.question,
options: args.options, options: args.options,
multi: args.multi, multi: args.multi,
@ -190,7 +191,7 @@ impl AgentServer {
}) })
.await; .await;
let s = match resp { let s = match resp {
Ok(hive_agent_sock::Response::QuestionQueued { id }) => format!( Ok(hive_core_agent_sock::Response::QuestionQueued { id }) => format!(
"question queued (id={id}); answer will arrive as a system \ "question queued (id={id}); answer will arrive as a system \
`question_answered` event in your inbox" `question_answered` event in your inbox"
), ),
@ -215,7 +216,7 @@ impl AgentServer {
let id = args.id; let id = args.id;
run_tool_envelope("answer", log, async move { run_tool_envelope("answer", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Answer { .dispatch(hive_core_agent_sock::Request::Answer {
id, id,
answer: args.answer, answer: args.answer,
}) })
@ -253,7 +254,7 @@ impl AgentServer {
run_tool_envelope("recv", log, async move { run_tool_envelope("recv", log, async move {
let waited = args.wait_seconds.is_some_and(|w| w > 0); let waited = args.wait_seconds.is_some_and(|w| w > 0);
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Recv { .dispatch(hive_core_agent_sock::Request::Recv {
wait_seconds: args.wait_seconds, wait_seconds: args.wait_seconds,
max: args.max, max: args.max,
}) })
@ -278,10 +279,10 @@ impl AgentServer {
let log = format!("{args:?}"); let log = format!("{args:?}");
run_tool_envelope("ack_until", log, async move { run_tool_envelope("ack_until", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::AckUntil { up_to: args.up_to }) .dispatch(hive_core_agent_sock::Request::AckUntil { up_to: args.up_to })
.await; .await;
let rendered = match resp { let rendered = match resp {
Ok(hive_agent_sock::Response::Acked { count }) => { Ok(hive_core_agent_sock::Response::Acked { count }) => {
format!("acked {count} message(s) up to id {}", args.up_to) format!("acked {count} message(s) up to id {}", args.up_to)
} }
other => reply_err(other, "ack_until"), other => reply_err(other, "ack_until"),
@ -310,11 +311,11 @@ impl AgentServer {
run_tool_envelope("get_loose_ends", String::new(), async move { run_tool_envelope("get_loose_ends", String::new(), async move {
let is_self_query = args.agent.is_none(); let is_self_query = args.agent.is_none();
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::GetLooseEnds { agent: args.agent }) .dispatch(hive_core_agent_sock::Request::GetLooseEnds { agent: args.agent })
.await; .await;
// Extract the vec so we can augment before rendering. // Extract the vec so we can augment before rendering.
let mut loose_ends = match resp { let mut loose_ends = match resp {
Ok(hive_agent_sock::Response::LooseEnds { loose_ends }) => loose_ends, Ok(hive_core_agent_sock::Response::LooseEnds { loose_ends }) => loose_ends,
other => return annotate_retries(reply_err(other, "get_loose_ends"), retries), other => return annotate_retries(reply_err(other, "get_loose_ends"), retries),
}; };
// Prepend matrix unread entry for self-queries only (can't // Prepend matrix unread entry for self-queries only (can't
@ -363,7 +364,7 @@ impl AgentServer {
return e; return e;
} }
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::SetStatus { text: args.text }) .dispatch(hive_core_agent_sock::Request::SetStatus { text: args.text })
.await; .await;
annotate_retries( annotate_retries(
format_ack(resp, "set_status", "status updated".to_owned()), format_ack(resp, "set_status", "status updated".to_owned()),
@ -395,7 +396,7 @@ impl AgentServer {
let log = args.name.clone().unwrap_or_else(|| "<self>".to_owned()); let log = args.name.clone().unwrap_or_else(|| "<self>".to_owned());
run_tool_envelope("get_agent_meta", log, async move { run_tool_envelope("get_agent_meta", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::GetAgentMeta { name: args.name }) .dispatch(hive_core_agent_sock::Request::GetAgentMeta { name: args.name })
.await; .await;
annotate_retries(format_agent_meta(resp), retries) annotate_retries(format_agent_meta(resp), retries)
}) })
@ -423,7 +424,7 @@ impl AgentServer {
}; };
let kind_label = loose_end_kind_label(kind); let kind_label = loose_end_kind_label(kind);
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::CancelLooseEnd { kind, id }) .dispatch(hive_core_agent_sock::Request::CancelLooseEnd { kind, id })
.await; .await;
annotate_retries( annotate_retries(
format_ack( format_ack(
@ -450,10 +451,10 @@ impl AgentServer {
let log = format!("{args:?}"); let log = format!("{args:?}");
run_tool_envelope("create_repo", log, async move { run_tool_envelope("create_repo", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::CreateRepo { repo: args.repo }) .dispatch(hive_core_agent_sock::Request::CreateRepo { repo: args.repo })
.await; .await;
let s = match resp { let s = match resp {
Ok(hive_agent_sock::Response::RepoCreated { Ok(hive_core_agent_sock::Response::RepoCreated {
full_name, full_name,
clone_url, clone_url,
}) => format!("created repo {full_name} — clone: {clone_url}"), }) => format!("created repo {full_name} — clone: {clone_url}"),
@ -493,7 +494,7 @@ impl AgentServer {
(None, Some(t)) => hive_sh4re::ReminderTiming::At { unix_timestamp: t }, (None, Some(t)) => hive_sh4re::ReminderTiming::At { unix_timestamp: t },
}; };
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Remind { .dispatch(hive_core_agent_sock::Request::Remind {
message: args.message, message: args.message,
timing, timing,
file_path: args.file_path, file_path: args.file_path,
@ -547,7 +548,7 @@ impl AgentServer {
let name = args.name.clone(); let name = args.name.clone();
run_tool_envelope("restart", log, async move { run_tool_envelope("restart", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Restart { name: args.name }) .dispatch(hive_core_agent_sock::Request::Restart { name: args.name })
.await; .await;
annotate_retries( annotate_retries(
format_ack(resp, "restart", format!("restarted {name}")), format_ack(resp, "restart", format!("restarted {name}")),
@ -569,7 +570,7 @@ impl AgentServer {
let name = args.name.clone(); let name = args.name.clone();
run_tool_envelope("kill", log, async move { run_tool_envelope("kill", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Kill { name: args.name }) .dispatch(hive_core_agent_sock::Request::Kill { name: args.name })
.await; .await;
annotate_retries(format_ack(resp, "kill", format!("killed {name}")), retries) annotate_retries(format_ack(resp, "kill", format!("killed {name}")), retries)
}) })
@ -590,7 +591,7 @@ impl AgentServer {
let name = args.name.clone(); let name = args.name.clone();
run_tool_envelope("update", log, async move { run_tool_envelope("update", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Update { name: args.name }) .dispatch(hive_core_agent_sock::Request::Update { name: args.name })
.await; .await;
annotate_retries( annotate_retries(
format_ack(resp, "update", format!("updated {name}")), format_ack(resp, "update", format!("updated {name}")),
@ -613,10 +614,10 @@ impl AgentServer {
async fn list_containers(&self) -> String { async fn list_containers(&self) -> String {
run_tool_envelope("list_containers", String::new(), async move { run_tool_envelope("list_containers", String::new(), async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::ListDescendants) .dispatch(hive_core_agent_sock::Request::ListDescendants)
.await; .await;
let body = match resp { let body = match resp {
Ok(hive_agent_sock::Response::Containers { containers }) => { Ok(hive_core_agent_sock::Response::Containers { containers }) => {
if containers.is_empty() { if containers.is_empty() {
"no descendant containers".to_owned() "no descendant containers".to_owned()
} else { } else {
@ -659,7 +660,7 @@ impl AgentServer {
let log = format!("{args:?}"); let log = format!("{args:?}");
run_tool_envelope("get_host_journal", log, async move { run_tool_envelope("get_host_journal", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::GetHostJournal { .dispatch(hive_core_agent_sock::Request::GetHostJournal {
unit: args.unit, unit: args.unit,
container: args.container, container: args.container,
lines: args.lines, lines: args.lines,
@ -670,7 +671,7 @@ impl AgentServer {
}) })
.await; .await;
let result = match resp { let result = match resp {
Ok(hive_agent_sock::Response::HostJournal { content }) => content, Ok(hive_core_agent_sock::Response::HostJournal { content }) => content,
other => reply_err(other, "get_host_journal"), other => reply_err(other, "get_host_journal"),
}; };
annotate_retries(result, retries) annotate_retries(result, retries)
@ -699,7 +700,7 @@ impl AgentServer {
let name = args.name.clone(); let name = args.name.clone();
run_tool_envelope("request_init_config", log, async move { run_tool_envelope("request_init_config", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::RequestInitConfig { .dispatch(hive_core_agent_sock::Request::RequestInitConfig {
name: args.name, name: args.name,
description: args.description, description: args.description,
}) })
@ -727,7 +728,7 @@ impl AgentServer {
let name = args.name.clone(); let name = args.name.clone();
run_tool_envelope("start", log, async move { run_tool_envelope("start", log, async move {
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::Start { name: args.name }) .dispatch(hive_core_agent_sock::Request::Start { name: args.name })
.await; .await;
annotate_retries( annotate_retries(
format_ack(resp, "start", format!("started {name}")), format_ack(resp, "start", format!("started {name}")),
@ -750,13 +751,13 @@ impl AgentServer {
run_tool_envelope("get_logs", log, async move { run_tool_envelope("get_logs", log, async move {
let lines = args.lines.map(|n| n.min(500)); let lines = args.lines.map(|n| n.min(500));
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::GetLogs { .dispatch(hive_core_agent_sock::Request::GetLogs {
agent: agent.clone(), agent: agent.clone(),
lines, lines,
}) })
.await; .await;
let s = match resp { let s = match resp {
Ok(hive_agent_sock::Response::Logs { content }) => { Ok(hive_core_agent_sock::Response::Logs { content }) => {
if content.is_empty() { if content.is_empty() {
format!("(no journal output for {agent})") format!("(no journal output for {agent})")
} else { } else {
@ -790,7 +791,7 @@ impl AgentServer {
args.inputs.join(", ") args.inputs.join(", ")
}; };
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::RequestUpdateMetaInputs { .dispatch(hive_core_agent_sock::Request::RequestUpdateMetaInputs {
inputs: args.inputs, inputs: args.inputs,
description: args.description, description: args.description,
}) })
@ -829,7 +830,7 @@ impl AgentServer {
run_tool_envelope("request_schedule_prompt", log, async move { run_tool_envelope("request_schedule_prompt", log, async move {
let target_count = args.targets.len(); let target_count = args.targets.len();
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::RequestSchedulePrompt( .dispatch(hive_core_agent_sock::Request::RequestSchedulePrompt(
hive_sh4re::SchedulePromptPayload { hive_sh4re::SchedulePromptPayload {
targets: args.targets, targets: args.targets,
body: args.body, body: args.body,
@ -865,7 +866,7 @@ impl AgentServer {
run_tool_envelope("fire_schedule_now", log, async move { run_tool_envelope("fire_schedule_now", log, async move {
let id = args.id; let id = args.id;
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::FireScheduleNow { id }) .dispatch(hive_core_agent_sock::Request::FireScheduleNow { id })
.await; .await;
annotate_retries( annotate_retries(
format_ack(resp, "fire_schedule_now", format!("fired #{id} now")), format_ack(resp, "fire_schedule_now", format!("fired #{id} now")),
@ -888,7 +889,7 @@ impl AgentServer {
run_tool_envelope("cancel_schedule", log, async move { run_tool_envelope("cancel_schedule", log, async move {
let id = args.id; let id = args.id;
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::CancelSchedule { .dispatch(hive_core_agent_sock::Request::CancelSchedule {
id: args.id, id: args.id,
targets: args.targets, targets: args.targets,
}) })
@ -920,7 +921,7 @@ impl AgentServer {
run_tool_envelope("edit_schedule", log, async move { run_tool_envelope("edit_schedule", log, async move {
let id = args.id; let id = args.id;
let (resp, retries) = self let (resp, retries) = self
.dispatch(hive_agent_sock::Request::EditSchedule { .dispatch(hive_core_agent_sock::Request::EditSchedule {
id: args.id, id: args.id,
body: args.body, body: args.body,
description: args.description.map(Some), description: args.description.map(Some),
@ -947,9 +948,11 @@ impl AgentServer {
)] )]
async fn list_schedules(&self) -> String { async fn list_schedules(&self) -> String {
run_tool_envelope("list_schedules", String::new(), async move { run_tool_envelope("list_schedules", String::new(), async move {
let (resp, retries) = self.dispatch(hive_agent_sock::Request::ListSchedules).await; let (resp, retries) = self
.dispatch(hive_core_agent_sock::Request::ListSchedules)
.await;
let body = match resp { let body = match resp {
Ok(hive_agent_sock::Response::Schedules { schedules }) => { Ok(hive_core_agent_sock::Response::Schedules { schedules }) => {
serde_json::to_string(&schedules) serde_json::to_string(&schedules)
.unwrap_or_else(|e| format!("list_schedules: serialise: {e:#}")) .unwrap_or_else(|e| format!("list_schedules: serialise: {e:#}"))
} }

View file

@ -11,11 +11,11 @@
/// everything else here via a catch-all arm (`other => reply_err(other, tool)`), /// everything else here via a catch-all arm (`other => reply_err(other, tool)`),
/// so the triplet lives in exactly one place. /// so the triplet lives in exactly one place.
pub(super) fn reply_err( pub(super) fn reply_err(
resp: Result<hive_agent_sock::Response, anyhow::Error>, resp: Result<hive_core_agent_sock::Response, anyhow::Error>,
tool: &str, tool: &str,
) -> String { ) -> String {
match resp { match resp {
Ok(hive_agent_sock::Response::Err { message }) => format!("{tool} failed: {message}"), Ok(hive_core_agent_sock::Response::Err { message }) => format!("{tool} failed: {message}"),
Ok(other) => format!("{tool} unexpected response: {other:?}"), Ok(other) => format!("{tool} unexpected response: {other:?}"),
Err(e) => format!("{tool} transport error: {e:#}"), Err(e) => format!("{tool} transport error: {e:#}"),
} }
@ -26,12 +26,12 @@ pub(super) fn reply_err(
/// behavior. /// behavior.
#[must_use] #[must_use]
pub fn format_ack( pub fn format_ack(
resp: Result<hive_agent_sock::Response, anyhow::Error>, resp: Result<hive_core_agent_sock::Response, anyhow::Error>,
tool: &str, tool: &str,
ok_msg: String, ok_msg: String,
) -> String { ) -> String {
match resp { match resp {
Ok(hive_agent_sock::Response::Ok) => ok_msg, Ok(hive_core_agent_sock::Response::Ok) => ok_msg,
other => reply_err(other, tool), other => reply_err(other, tool),
} }
} }
@ -47,9 +47,12 @@ pub fn format_ack(
/// so the model can tell where one ends and the next begins; /// so the model can tell where one ends and the next begins;
/// per-message redelivery banners included. /// per-message redelivery banners included.
#[must_use] #[must_use]
pub fn format_recv(resp: Result<hive_agent_sock::Response, anyhow::Error>, waited: bool) -> String { pub fn format_recv(
resp: Result<hive_core_agent_sock::Response, anyhow::Error>,
waited: bool,
) -> String {
match resp { match resp {
Ok(hive_agent_sock::Response::Messages { Ok(hive_core_agent_sock::Response::Messages {
messages, messages,
remaining, remaining,
}) => render_recv_messages(&messages, remaining, waited), }) => render_recv_messages(&messages, remaining, waited),
@ -60,7 +63,7 @@ pub fn format_recv(resp: Result<hive_agent_sock::Response, anyhow::Error>, waite
// stop unmissably tells claude to flush + end. `remaining` is forced // stop unmissably tells claude to flush + end. `remaining` is forced
// to 0 — the inbox is fenced, so a "N more pending" hint would be // to 0 — the inbox is fenced, so a "N more pending" hint would be
// misleading. // misleading.
Ok(hive_agent_sock::Response::GracefulStop) => { Ok(hive_core_agent_sock::Response::GracefulStop) => {
render_recv_messages(&[graceful_stop_message()], 0, waited) render_recv_messages(&[graceful_stop_message()], 0, waited)
} }
other => reply_err(other, "recv"), other => reply_err(other, "recv"),
@ -357,9 +360,9 @@ pub(super) fn loose_end_kind_label(kind: hive_sh4re::CancelLooseEndKind) -> &'st
/// `running: no` line tells the caller WHY. See /// `running: no` line tells the caller WHY. See
/// `docs/turn-loop/mcp.md::Core tools` (`get_agent_meta`). /// `docs/turn-loop/mcp.md::Core tools` (`get_agent_meta`).
#[must_use] #[must_use]
pub fn format_agent_meta(resp: Result<hive_agent_sock::Response, anyhow::Error>) -> String { pub fn format_agent_meta(resp: Result<hive_core_agent_sock::Response, anyhow::Error>) -> String {
match resp { match resp {
Ok(hive_agent_sock::Response::AgentMeta { Ok(hive_core_agent_sock::Response::AgentMeta {
name, name,
running, running,
hyperhive_rev, hyperhive_rev,
@ -480,7 +483,7 @@ mod tests {
#[test] #[test]
fn empty_recv_after_wait_appends_idle_hint() { fn empty_recv_after_wait_appends_idle_hint() {
let out = format_recv( let out = format_recv(
Ok(hive_agent_sock::Response::Messages { Ok(hive_core_agent_sock::Response::Messages {
messages: vec![], messages: vec![],
remaining: 0, remaining: 0,
}), }),
@ -493,7 +496,7 @@ mod tests {
#[test] #[test]
fn empty_recv_without_wait_has_no_hint() { fn empty_recv_without_wait_has_no_hint() {
let out = format_recv( let out = format_recv(
Ok(hive_agent_sock::Response::Messages { Ok(hive_core_agent_sock::Response::Messages {
messages: vec![], messages: vec![],
remaining: 0, remaining: 0,
}), }),
@ -505,7 +508,7 @@ mod tests {
#[test] #[test]
fn single_recv_with_remaining_appends_pending_hint() { fn single_recv_with_remaining_appends_pending_hint() {
let out = format_recv( let out = format_recv(
Ok(hive_agent_sock::Response::Messages { Ok(hive_core_agent_sock::Response::Messages {
messages: vec![msg(7, "alice", "hi")], messages: vec![msg(7, "alice", "hi")],
remaining: 3, remaining: 3,
}), }),
@ -519,7 +522,7 @@ mod tests {
#[test] #[test]
fn single_recv_no_remaining_has_no_pending_hint() { fn single_recv_no_remaining_has_no_pending_hint() {
let out = format_recv( let out = format_recv(
Ok(hive_agent_sock::Response::Messages { Ok(hive_core_agent_sock::Response::Messages {
messages: vec![msg(7, "alice", "hi")], messages: vec![msg(7, "alice", "hi")],
remaining: 0, remaining: 0,
}), }),
@ -531,7 +534,7 @@ mod tests {
#[test] #[test]
fn batch_recv_with_remaining_appends_pending_hint_once() { fn batch_recv_with_remaining_appends_pending_hint_once() {
let out = format_recv( let out = format_recv(
Ok(hive_agent_sock::Response::Messages { Ok(hive_core_agent_sock::Response::Messages {
messages: vec![msg(7, "alice", "hi"), msg(8, "bob", "yo")], messages: vec![msg(7, "alice", "hi"), msg(8, "bob", "yo")],
remaining: 9, remaining: 9,
}), }),

View file

@ -13,7 +13,7 @@ workspace = true
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
clap.workspace = true clap.workspace = true
hive-agent-sock.workspace = true hive-core-agent-sock.workspace = true
serde.workspace = true serde.workspace = true
serde_json.workspace = true serde_json.workspace = true
tokio.workspace = true tokio.workspace = true

View file

@ -13,7 +13,7 @@ use std::path::PathBuf;
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
use hive_agent_sock::{Request, Response}; use hive_core_agent_sock::{Request, Response};
/// Per-agent MCP socket, bind-mounted from the host into every container. /// Per-agent MCP socket, bind-mounted from the host into every container.
const DEFAULT_SOCKET: &str = "/run/hive/mcp.sock"; const DEFAULT_SOCKET: &str = "/run/hive/mcp.sock";

View file

@ -19,7 +19,7 @@ time.workspace = true
futures-util = "0.3" futures-util = "0.3"
clap.workspace = true clap.workspace = true
hive-claude.workspace = true hive-claude.workspace = true
hive-agent-sock.workspace = true hive-core-agent-sock.workspace = true
hive-sh4re.workspace = true hive-sh4re.workspace = true
rmcp.workspace = true rmcp.workspace = true
rusqlite.workspace = true rusqlite.workspace = true

View file

@ -1064,13 +1064,14 @@ async fn poll_once(
continue; continue;
}; };
let req = hive_agent_sock::Request::Wake { let req = hive_core_agent_sock::Request::Wake {
from: "forge".to_owned(), from: "forge".to_owned(),
body, body,
}; };
let deliver_result = crate::client::request::<_, hive_agent_sock::Response>(socket, &req) let deliver_result =
.await crate::client::request::<_, hive_core_agent_sock::Response>(socket, &req)
.map(|_| ()); .await
.map(|_| ());
match deliver_result { match deliver_result {
Ok(()) => { Ok(()) => {
debug!(%id, "forge_notify: delivered"); debug!(%id, "forge_notify: delivered");

View file

@ -43,7 +43,7 @@ use crate::login::LoginState;
use crate::turn_stats::TurnStats; use crate::turn_stats::TurnStats;
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
use hive_agent_sock::{Request, Response}; use hive_core_agent_sock::{Request, Response};
use hive_sh4re::{HelperEvent, SYSTEM_SENDER}; use hive_sh4re::{HelperEvent, SYSTEM_SENDER};
#[derive(Parser)] #[derive(Parser)]

View file

@ -25,7 +25,7 @@ pub(super) async fn post_send(
} }
match super::broker_request( match super::broker_request(
&state.socket, &state.socket,
&hive_agent_sock::Request::OperatorMsg { body }, &hive_core_agent_sock::Request::OperatorMsg { body },
) )
.await .await
{ {
@ -35,8 +35,10 @@ pub(super) async fn post_send(
// resulting `TurnStart` SSE event drives the terminal + the // resulting `TurnStart` SSE event drives the terminal + the
// inbox row gets consumed by the time `TurnEnd` fires the // inbox row gets consumed by the time `TurnEnd` fires the
// existing turn-end refresh. // existing turn-end refresh.
Ok(hive_agent_sock::Response::Ok) => (axum::http::StatusCode::OK, "ok").into_response(), Ok(hive_core_agent_sock::Response::Ok) => {
Ok(hive_agent_sock::Response::Err { message }) => error_response( (axum::http::StatusCode::OK, "ok").into_response()
}
Ok(hive_core_agent_sock::Response::Err { message }) => error_response(
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
&format!("send failed: {message}"), &format!("send failed: {message}"),
), ),

View file

@ -302,11 +302,11 @@ enum BrokerError {
/// web-UI handler that talks to the broker goes through it. /// web-UI handler that talks to the broker goes through it.
async fn broker_request( async fn broker_request(
socket: &Path, socket: &Path,
req: &hive_agent_sock::Request, req: &hive_core_agent_sock::Request,
) -> std::result::Result<hive_agent_sock::Response, BrokerError> { ) -> std::result::Result<hive_core_agent_sock::Response, BrokerError> {
match tokio::time::timeout( match tokio::time::timeout(
SOCKET_FETCH_TIMEOUT, SOCKET_FETCH_TIMEOUT,
crate::client::request::<_, hive_agent_sock::Response>(socket, req), crate::client::request::<_, hive_core_agent_sock::Response>(socket, req),
) )
.await .await
{ {

View file

@ -366,8 +366,13 @@ async fn recent_inbox(socket: &std::path::Path) -> Vec<hive_sh4re::InboxRow> {
const LIMIT: u64 = 30; const LIMIT: u64 = 30;
// Deadline-bounded (via `broker_request`): `/api/state` must render even // Deadline-bounded (via `broker_request`): `/api/state` must render even
// when hive-c0re is busy — an empty inbox section beats a hung snapshot. // when hive-c0re is busy — an empty inbox section beats a hung snapshot.
match super::broker_request(socket, &hive_agent_sock::Request::Recent { limit: LIMIT }).await { match super::broker_request(
Ok(hive_agent_sock::Response::Recent { rows }) => rows, socket,
&hive_core_agent_sock::Request::Recent { limit: LIMIT },
)
.await
{
Ok(hive_core_agent_sock::Response::Recent { rows }) => rows,
_ => Vec::new(), _ => Vec::new(),
} }
} }

View file

@ -35,14 +35,14 @@ async fn fetch_reminder_stats(
) -> Option<hive_sh4re::ReminderStats> { ) -> Option<hive_sh4re::ReminderStats> {
match super::broker_request( match super::broker_request(
socket, socket,
&hive_agent_sock::Request::ReminderRollup { &hive_core_agent_sock::Request::ReminderRollup {
since_secs: window_secs, since_secs: window_secs,
agent: None, agent: None,
}, },
) )
.await .await
{ {
Ok(hive_agent_sock::Response::ReminderRollup(stats)) => Some(stats), Ok(hive_core_agent_sock::Response::ReminderRollup(stats)) => Some(stats),
_ => None, _ => None,
} }
} }
@ -57,14 +57,14 @@ async fn fetch_reminder_stats(
pub(super) async fn api_loose_ends(State(state): State<AppState>) -> Response { pub(super) async fn api_loose_ends(State(state): State<AppState>) -> Response {
match super::broker_request( match super::broker_request(
&state.socket, &state.socket,
&hive_agent_sock::Request::GetLooseEnds { agent: None }, &hive_core_agent_sock::Request::GetLooseEnds { agent: None },
) )
.await .await
{ {
Ok(hive_agent_sock::Response::LooseEnds { loose_ends }) => { Ok(hive_core_agent_sock::Response::LooseEnds { loose_ends }) => {
axum::Json(serde_json::json!({ "loose_ends": loose_ends })).into_response() axum::Json(serde_json::json!({ "loose_ends": loose_ends })).into_response()
} }
Ok(hive_agent_sock::Response::Err { message }) => error_response( Ok(hive_core_agent_sock::Response::Err { message }) => error_response(
StatusCode::INTERNAL_SERVER_ERROR, StatusCode::INTERNAL_SERVER_ERROR,
&format!("get_loose_ends: {message}"), &format!("get_loose_ends: {message}"),
), ),

View file

@ -8,7 +8,7 @@ workspace = true
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
hive-agent-sock.workspace = true hive-core-agent-sock.workspace = true
hive-sh4re.workspace = true hive-sh4re.workspace = true
libc.workspace = true libc.workspace = true
rmcp.workspace = true rmcp.workspace = true

View file

@ -760,7 +760,7 @@ pub(crate) async fn send_wake(
); );
} }
} }
let req = hive_agent_sock::Request::Wake { let req = hive_core_agent_sock::Request::Wake {
from: format!("bash-task-{id}"), from: format!("bash-task-{id}"),
body, body,
}; };

View file

@ -30,7 +30,7 @@ opentelemetry-otlp = { version = "0.32", default-features = false, features = [
"reqwest-rustls", "reqwest-rustls",
] } ] }
indicatif.workspace = true indicatif.workspace = true
hive-agent-sock.workspace = true hive-core-agent-sock.workspace = true
hive-sh4re.workspace = true hive-sh4re.workspace = true
hive-host-sock.workspace = true hive-host-sock.workspace = true
hive-priv-sock.workspace = true hive-priv-sock.workspace = true

View file

@ -9,7 +9,7 @@
use std::sync::Arc; use std::sync::Arc;
use hive_agent_sock::Response; use hive_core_agent_sock::Response;
use super::require_new_child; use super::require_new_child;
use crate::coordinator::Coordinator; use crate::coordinator::Coordinator;

View file

@ -5,7 +5,7 @@
use std::sync::Arc; use std::sync::Arc;
use hive_agent_sock::Response; use hive_core_agent_sock::Response;
use super::require_descendant; use super::require_descendant;
use crate::coordinator::Coordinator; use crate::coordinator::Coordinator;

View file

@ -13,7 +13,7 @@ use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use hive_agent_sock::{Request, Response}; use hive_core_agent_sock::{Request, Response};
use hive_sh4re::{MANAGER_AGENT, Message}; use hive_sh4re::{MANAGER_AGENT, Message};
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::net::{UnixListener, UnixStream}; use tokio::net::{UnixListener, UnixStream};
@ -190,24 +190,26 @@ pub(crate) fn recv_timeout(wait_seconds: Option<u64>) -> std::time::Duration {
/// The unified `dispatch` calls this first; the remaining arms (which gate /// The unified `dispatch` calls this first; the remaining arms (which gate
/// on topology / capabilities / tool-groups) are handled there. /// on topology / capabilities / tool-groups) are handled there.
pub(crate) async fn dispatch_shared( pub(crate) async fn dispatch_shared(
req: &hive_agent_sock::Request, req: &hive_core_agent_sock::Request,
agent: &str, agent: &str,
coord: &Arc<Coordinator>, coord: &Arc<Coordinator>,
) -> Option<hive_agent_sock::Response> { ) -> Option<hive_core_agent_sock::Response> {
Some(match req { Some(match req {
hive_agent_sock::Request::Send { hive_core_agent_sock::Request::Send {
to, to,
body, body,
in_reply_to, in_reply_to,
} => handle_send(coord, agent, to, body, *in_reply_to), } => handle_send(coord, agent, to, body, *in_reply_to),
hive_agent_sock::Request::Recv { wait_seconds, max } => { hive_core_agent_sock::Request::Recv { wait_seconds, max } => {
handle_recv(coord, agent, *wait_seconds, *max).await handle_recv(coord, agent, *wait_seconds, *max).await
} }
hive_agent_sock::Request::Status => handle_status(coord, agent), hive_core_agent_sock::Request::Status => handle_status(coord, agent),
hive_agent_sock::Request::OperatorMsg { body } => handle_operator_msg(coord, agent, body), hive_core_agent_sock::Request::OperatorMsg { body } => {
hive_agent_sock::Request::Wake { from, body } => handle_wake(coord, agent, from, body), handle_operator_msg(coord, agent, body)
hive_agent_sock::Request::Recent { limit } => handle_recent(coord, agent, *limit), }
hive_agent_sock::Request::Ask { hive_core_agent_sock::Request::Wake { from, body } => handle_wake(coord, agent, from, body),
hive_core_agent_sock::Request::Recent { limit } => handle_recent(coord, agent, *limit),
hive_core_agent_sock::Request::Ask {
question, question,
options, options,
multi, multi,
@ -223,42 +225,42 @@ pub(crate) async fn dispatch_shared(
to.as_deref(), to.as_deref(),
) )
.map_or_else( .map_or_else(
|message| hive_agent_sock::Response::Err { message }, |message| hive_core_agent_sock::Response::Err { message },
|id| hive_agent_sock::Response::QuestionQueued { id }, |id| hive_core_agent_sock::Response::QuestionQueued { id },
), ),
hive_agent_sock::Request::Answer { id, answer } => { hive_core_agent_sock::Request::Answer { id, answer } => {
crate::questions::handle_answer(coord, agent, *id, answer).map_or_else( crate::questions::handle_answer(coord, agent, *id, answer).map_or_else(
|message| hive_agent_sock::Response::Err { message }, |message| hive_core_agent_sock::Response::Err { message },
|()| hive_agent_sock::Response::Ok, |()| hive_core_agent_sock::Response::Ok,
) )
} }
hive_agent_sock::Request::Remind { hive_core_agent_sock::Request::Remind {
message, message,
timing, timing,
file_path, file_path,
} => handle_remind(coord, agent, message, timing, file_path.as_deref()), } => handle_remind(coord, agent, message, timing, file_path.as_deref()),
hive_agent_sock::Request::SetStatus { text } => handle_set_status(coord, text), hive_core_agent_sock::Request::SetStatus { text } => handle_set_status(coord, text),
hive_agent_sock::Request::GetAgentMeta { name } => { hive_core_agent_sock::Request::GetAgentMeta { name } => {
handle_get_agent_meta(coord, agent, name.as_deref()).await handle_get_agent_meta(coord, agent, name.as_deref()).await
} }
hive_agent_sock::Request::CancelLooseEnd { kind, id } => { hive_core_agent_sock::Request::CancelLooseEnd { kind, id } => {
crate::questions::handle_cancel_loose_end(coord, agent, *kind, *id).map_or_else( crate::questions::handle_cancel_loose_end(coord, agent, *kind, *id).map_or_else(
|message| hive_agent_sock::Response::Err { message }, |message| hive_core_agent_sock::Response::Err { message },
|()| hive_agent_sock::Response::Ok, |()| hive_core_agent_sock::Response::Ok,
) )
} }
hive_agent_sock::Request::CreateRepo { repo } => handle_create_repo(agent, repo).await, hive_core_agent_sock::Request::CreateRepo { repo } => handle_create_repo(agent, repo).await,
hive_agent_sock::Request::AckTurn => handle_ack_turn(coord, agent), hive_core_agent_sock::Request::AckTurn => handle_ack_turn(coord, agent),
hive_agent_sock::Request::AckUntil { up_to } => handle_ack_until(coord, agent, *up_to), hive_core_agent_sock::Request::AckUntil { up_to } => handle_ack_until(coord, agent, *up_to),
hive_agent_sock::Request::RequeueInflight => handle_requeue_inflight(coord, agent), hive_core_agent_sock::Request::RequeueInflight => handle_requeue_inflight(coord, agent),
hive_agent_sock::Request::GracefulStopComplete => { hive_core_agent_sock::Request::GracefulStopComplete => {
// Harness drained + is exiting: clear the fence so the // Harness drained + is exiting: clear the fence so the
// `GracefulStop` orchestration (which polls this flag) proceeds // `GracefulStop` orchestration (which polls this flag) proceeds
// to stop the container without waiting out its timeout. // to stop the container without waiting out its timeout.
coord.clear_graceful_stop(agent); coord.clear_graceful_stop(agent);
hive_agent_sock::Response::Ok hive_core_agent_sock::Response::Ok
} }
hive_agent_sock::Request::GetHostJournal { hive_core_agent_sock::Request::GetHostJournal {
unit, unit,
container, container,
lines, lines,
@ -293,7 +295,7 @@ async fn handle_recv(
agent: &str, agent: &str,
wait_seconds: Option<u64>, wait_seconds: Option<u64>,
max: Option<u32>, max: Option<u32>,
) -> hive_agent_sock::Response { ) -> hive_core_agent_sock::Response {
// Graceful-stop fence: while a graceful stop is pending for this agent, // Graceful-stop fence: while a graceful stop is pending for this agent,
// return `GracefulStop` instead of polling the broker. The harness runs // return `GracefulStop` instead of polling the broker. The harness runs
// one stop-checkpoint turn then exits; new sends keep queueing in the // one stop-checkpoint turn then exits; new sends keep queueing in the
@ -301,7 +303,7 @@ async fn handle_recv(
// so a flag set between polls is seen on the next Recv — the orchestration // so a flag set between polls is seen on the next Recv — the orchestration
// also fires a transient wake to break an in-flight long-poll. // also fires a transient wake to break an in-flight long-poll.
if coord.is_graceful_stop_pending(agent) { if coord.is_graceful_stop_pending(agent) {
return hive_agent_sock::Response::GracefulStop; return hive_core_agent_sock::Response::GracefulStop;
} }
let cap = max.unwrap_or(1).min(RECV_BATCH_MAX) as usize; let cap = max.unwrap_or(1).min(RECV_BATCH_MAX) as usize;
match coord match coord
@ -315,7 +317,7 @@ async fn handle_recv(
// exactly how many still-pending messages remain to drain. A count // exactly how many still-pending messages remain to drain. A count
// error is non-fatal — fall back to 0 rather than fail the recv. // error is non-fatal — fall back to 0 rather than fail the recv.
let remaining = coord.broker.count_pending(agent).unwrap_or(0); let remaining = coord.broker.count_pending(agent).unwrap_or(0);
hive_agent_sock::Response::Messages { hive_core_agent_sock::Response::Messages {
messages: deliveries messages: deliveries
.into_iter() .into_iter()
.map(|d| hive_sh4re::DeliveredMessage { .map(|d| hive_sh4re::DeliveredMessage {
@ -329,7 +331,7 @@ async fn handle_recv(
remaining, remaining,
} }
} }
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("{e:#}"), message: format!("{e:#}"),
}, },
} }
@ -343,15 +345,15 @@ fn handle_wake(
agent: &str, agent: &str,
from: &str, from: &str,
body: &str, body: &str,
) -> hive_agent_sock::Response { ) -> hive_core_agent_sock::Response {
match coord.broker.send(&Message { match coord.broker.send(&Message {
from: from.to_owned(), from: from.to_owned(),
to: agent.to_owned(), to: agent.to_owned(),
body: body.to_owned(), body: body.to_owned(),
in_reply_to: None, in_reply_to: None,
}) { }) {
Ok(()) => hive_agent_sock::Response::Ok, Ok(()) => hive_core_agent_sock::Response::Ok,
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("{e:#}"), message: format!("{e:#}"),
}, },
} }
@ -361,13 +363,13 @@ fn handle_wake(
/// rescan. The harness has already written the status file to its own /// rescan. The harness has already written the status file to its own
/// `state/` dir (it runs as the agent user), so this only refreshes the /// `state/` dir (it runs as the agent user), so this only refreshes the
/// dashboard's view. /// dashboard's view.
fn handle_set_status(coord: &Arc<Coordinator>, text: &str) -> hive_agent_sock::Response { fn handle_set_status(coord: &Arc<Coordinator>, text: &str) -> hive_core_agent_sock::Response {
if let Err(message) = crate::limits::check_status_text(text) { if let Err(message) = crate::limits::check_status_text(text) {
return hive_agent_sock::Response::Err { message }; return hive_core_agent_sock::Response::Err { message };
} }
let coord2 = Arc::clone(coord); let coord2 = Arc::clone(coord);
tokio::spawn(async move { coord2.rescan_containers_and_emit().await }); tokio::spawn(async move { coord2.rescan_containers_and_emit().await });
hive_agent_sock::Response::Ok hive_core_agent_sock::Response::Ok
} }
/// Validate an agent-supplied repo name: a single safe slug segment, no /// Validate an agent-supplied repo name: a single safe slug segment, no
@ -385,9 +387,9 @@ fn valid_repo_name(name: &str) -> bool {
/// `CreateRepo` — create a repo for `agent` *through hive-c0re* in the /// `CreateRepo` — create a repo for `agent` *through hive-c0re* in the
/// c0re-owned `agents` org with operator-team branch protection. /// c0re-owned `agents` org with operator-team branch protection.
/// The sanctioned create path now that agents can't create repos directly. /// The sanctioned create path now that agents can't create repos directly.
async fn handle_create_repo(agent: &str, repo: &str) -> hive_agent_sock::Response { async fn handle_create_repo(agent: &str, repo: &str) -> hive_core_agent_sock::Response {
if !valid_repo_name(repo) { if !valid_repo_name(repo) {
return hive_agent_sock::Response::Err { return hive_core_agent_sock::Response::Err {
message: format!( message: format!(
"invalid repo name {repo:?} — single segment of letters, digits, '-', '_', '.' \ "invalid repo name {repo:?} — single segment of letters, digits, '-', '_', '.' \
(no leading '-'/'.', max 100 chars)" (no leading '-'/'.', max 100 chars)"
@ -395,16 +397,16 @@ async fn handle_create_repo(agent: &str, repo: &str) -> hive_agent_sock::Respons
}; };
} }
let Some(core_token) = crate::forge::core_token() else { let Some(core_token) = crate::forge::core_token() else {
return hive_agent_sock::Response::Err { return hive_core_agent_sock::Response::Err {
message: "forge unavailable (no core token) — cannot create repo".to_owned(), message: "forge unavailable (no core token) — cannot create repo".to_owned(),
}; };
}; };
match crate::forge::create_agent_repo(agent, repo, &core_token).await { match crate::forge::create_agent_repo(agent, repo, &core_token).await {
Ok(full_name) => hive_agent_sock::Response::RepoCreated { Ok(full_name) => hive_core_agent_sock::Response::RepoCreated {
clone_url: format!("{}/{full_name}.git", crate::forge::forge_http_base()), clone_url: format!("{}/{full_name}.git", crate::forge::forge_http_base()),
full_name, full_name,
}, },
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("create repo {repo:?} failed: {e:#}"), message: format!("create repo {repo:?} failed: {e:#}"),
}, },
} }
@ -417,7 +419,7 @@ async fn handle_get_agent_meta(
coord: &Arc<Coordinator>, coord: &Arc<Coordinator>,
agent: &str, agent: &str,
name: Option<&str>, name: Option<&str>,
) -> hive_agent_sock::Response { ) -> hive_core_agent_sock::Response {
let target = name.unwrap_or(agent); let target = name.unwrap_or(agent);
// `name` is agent-supplied and flows into filesystem reads below // `name` is agent-supplied and flows into filesystem reads below
// (`read_agent_status_live`, `read_agent_matrix_identities` → // (`read_agent_status_live`, `read_agent_matrix_identities` →
@ -428,7 +430,7 @@ async fn handle_get_agent_meta(
let target_id = match hive_types::Ident::parse(target) { let target_id = match hive_types::Ident::parse(target) {
Ok(id) => id, Ok(id) => id,
Err(reason) => { Err(reason) => {
return hive_agent_sock::Response::Err { return hive_core_agent_sock::Response::Err {
message: format!("get_agent_meta: invalid agent name {target:?}: {reason}"), message: format!("get_agent_meta: invalid agent name {target:?}: {reason}"),
}; };
} }
@ -436,7 +438,7 @@ async fn handle_get_agent_meta(
let (status_text, status_set_at, running) = let (status_text, status_set_at, running) =
crate::container_view::read_agent_status_live(&target_id).await; crate::container_view::read_agent_status_live(&target_id).await;
let (hive_name, swarm_name) = crate::container_view::hive_swarm_names(); let (hive_name, swarm_name) = crate::container_view::hive_swarm_names();
hive_agent_sock::Response::AgentMeta { hive_core_agent_sock::Response::AgentMeta {
name: target.to_owned(), name: target.to_owned(),
running, running,
hyperhive_rev: crate::auto_update::current_flake_rev(&coord.hyperhive_flake), hyperhive_rev: crate::auto_update::current_flake_rev(&coord.hyperhive_flake),
@ -470,10 +472,10 @@ fn read_agent_matrix_identities(agent: &hive_types::Ident) -> Vec<hive_sh4re::Ma
} }
/// `Status` — count of pending (unread) inbox messages for `agent`. /// `Status` — count of pending (unread) inbox messages for `agent`.
fn handle_status(coord: &Arc<Coordinator>, agent: &str) -> hive_agent_sock::Response { fn handle_status(coord: &Arc<Coordinator>, agent: &str) -> hive_core_agent_sock::Response {
match coord.broker.count_pending(agent) { match coord.broker.count_pending(agent) {
Ok(unread) => hive_agent_sock::Response::Status { unread }, Ok(unread) => hive_core_agent_sock::Response::Status { unread },
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("{e:#}"), message: format!("{e:#}"),
}, },
} }
@ -485,15 +487,15 @@ fn handle_operator_msg(
coord: &Arc<Coordinator>, coord: &Arc<Coordinator>,
agent: &str, agent: &str,
body: &str, body: &str,
) -> hive_agent_sock::Response { ) -> hive_core_agent_sock::Response {
match coord.broker.send(&Message { match coord.broker.send(&Message {
from: hive_sh4re::OPERATOR_RECIPIENT.to_owned(), from: hive_sh4re::OPERATOR_RECIPIENT.to_owned(),
to: agent.to_owned(), to: agent.to_owned(),
body: body.to_owned(), body: body.to_owned(),
in_reply_to: None, in_reply_to: None,
}) { }) {
Ok(()) => hive_agent_sock::Response::Ok, Ok(()) => hive_core_agent_sock::Response::Ok,
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("{e:#}"), message: format!("{e:#}"),
}, },
} }
@ -501,10 +503,14 @@ fn handle_operator_msg(
/// `Recent` — the last `limit` inbox rows for `agent` (read-only, /// `Recent` — the last `limit` inbox rows for `agent` (read-only,
/// doesn't consume). /// doesn't consume).
fn handle_recent(coord: &Arc<Coordinator>, agent: &str, limit: u64) -> hive_agent_sock::Response { fn handle_recent(
coord: &Arc<Coordinator>,
agent: &str,
limit: u64,
) -> hive_core_agent_sock::Response {
match coord.broker.recent_for(agent, limit) { match coord.broker.recent_for(agent, limit) {
Ok(rows) => hive_agent_sock::Response::Recent { rows }, Ok(rows) => hive_core_agent_sock::Response::Recent { rows },
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("{e:#}"), message: format!("{e:#}"),
}, },
} }
@ -512,10 +518,10 @@ fn handle_recent(coord: &Arc<Coordinator>, agent: &str, limit: u64) -> hive_agen
/// `AckTurn` — mark `agent`'s in-flight delivered messages acked so /// `AckTurn` — mark `agent`'s in-flight delivered messages acked so
/// they don't redeliver on the next turn. /// they don't redeliver on the next turn.
fn handle_ack_turn(coord: &Arc<Coordinator>, agent: &str) -> hive_agent_sock::Response { fn handle_ack_turn(coord: &Arc<Coordinator>, agent: &str) -> hive_core_agent_sock::Response {
match coord.broker.ack_turn(agent) { match coord.broker.ack_turn(agent) {
Ok(_n) => hive_agent_sock::Response::Ok, Ok(_n) => hive_core_agent_sock::Response::Ok,
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("{e:#}"), message: format!("{e:#}"),
}, },
} }
@ -527,10 +533,10 @@ fn handle_ack_until(
coord: &Arc<Coordinator>, coord: &Arc<Coordinator>,
agent: &str, agent: &str,
up_to: i64, up_to: i64,
) -> hive_agent_sock::Response { ) -> hive_core_agent_sock::Response {
match coord.broker.ack_until(agent, up_to) { match coord.broker.ack_until(agent, up_to) {
Ok(count) => hive_agent_sock::Response::Acked { count }, Ok(count) => hive_core_agent_sock::Response::Acked { count },
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("{e:#}"), message: format!("{e:#}"),
}, },
} }
@ -538,15 +544,18 @@ fn handle_ack_until(
/// `RequeueInflight` — resurface `agent`'s unacked in-flight messages /// `RequeueInflight` — resurface `agent`'s unacked in-flight messages
/// (crash recovery on harness boot). /// (crash recovery on harness boot).
fn handle_requeue_inflight(coord: &Arc<Coordinator>, agent: &str) -> hive_agent_sock::Response { fn handle_requeue_inflight(
coord: &Arc<Coordinator>,
agent: &str,
) -> hive_core_agent_sock::Response {
match coord.broker.requeue_inflight(agent) { match coord.broker.requeue_inflight(agent) {
Ok(n) => { Ok(n) => {
if n > 0 { if n > 0 {
tracing::info!(%agent, requeued = %n, "requeued in-flight messages"); tracing::info!(%agent, requeued = %n, "requeued in-flight messages");
} }
hive_agent_sock::Response::Ok hive_core_agent_sock::Response::Ok
} }
Err(e) => hive_agent_sock::Response::Err { Err(e) => hive_core_agent_sock::Response::Err {
message: format!("{e:#}"), message: format!("{e:#}"),
}, },
} }

View file

@ -5,7 +5,7 @@
use std::sync::Arc; use std::sync::Arc;
use hive_agent_sock::Response; use hive_core_agent_sock::Response;
use crate::coordinator::Coordinator; use crate::coordinator::Coordinator;

View file

@ -6,7 +6,7 @@
use std::sync::Arc; use std::sync::Arc;
use hive_agent_sock::Response; use hive_core_agent_sock::Response;
use crate::coordinator::Coordinator; use crate::coordinator::Coordinator;

View file

@ -1,5 +1,5 @@
[package] [package]
name = "hive-agent-sock" name = "hive-core-agent-sock"
edition.workspace = true edition.workspace = true
version.workspace = true version.workspace = true

View file

@ -24,7 +24,7 @@ use tokio::net::UnixStream;
/// failure; callers log + ignore so a wake delivery hiccup doesn't tear /// failure; callers log + ignore so a wake delivery hiccup doesn't tear
/// down the matrix sync loop. /// down the matrix sync loop.
/// ///
/// Wire format matches `hive_agent_sock::Request` tagged with `"cmd"` per /// Wire format matches `hive_core_agent_sock::Request` tagged with `"cmd"` per
/// `#[serde(tag = "cmd", rename_all = "snake_case")]`. Must be `"cmd"`, /// `#[serde(tag = "cmd", rename_all = "snake_case")]`. Must be `"cmd"`,
/// not `"kind"` — the harness deserialises against the hive-sh4re type /// not `"kind"` — the harness deserialises against the hive-sh4re type
/// and silently discards requests that don't match. /// and silently discards requests that don't match.

View file

@ -1,7 +1,7 @@
//! Foundational shared newtypes for the hyperhive workspace. //! Foundational shared newtypes for the hyperhive workspace.
//! //!
//! A zero-dependency (bar `serde`) leaf crate so every wire-type crate //! A zero-dependency (bar `serde`) leaf crate so every wire-type crate
//! (`hive-sh4re`, `hive-host-sock`, `hive-agent-sock`) and both binaries //! (`hive-sh4re`, `hive-host-sock`, `hive-core-agent-sock`) and both binaries
//! (`hive-c0re`, `hivectl`) can type their agent-name fields as [`Ident`] //! (`hive-c0re`, `hivectl`) can type their agent-name fields as [`Ident`]
//! and get serde-validated parsing at the socket boundary for free — with //! and get serde-validated parsing at the socket boundary for free — with
//! no cross-crate coupling and without growing `hive-sh4re`. //! no cross-crate coupling and without growing `hive-sh4re`.