Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cf7f043ad | ||
|
|
7261992fda | ||
|
|
3c5abd3c85 | ||
|
|
c634dab2a6 |
4 changed files with 319 additions and 723 deletions
|
|
@ -311,10 +311,10 @@ from `tool-groups.json`). Unrecognised tokens are logged and skipped. Falls back
|
||||||
to `ToolGroup::AGENT_DEFAULT` (`messaging`, `meta`, `inbox`, `execution`) or
|
to `ToolGroup::AGENT_DEFAULT` (`messaging`, `meta`, `inbox`, `execution`) or
|
||||||
`ToolGroup::MANAGER_DEFAULT` (all groups) when the var is absent or empty.
|
`ToolGroup::MANAGER_DEFAULT` (all groups) when the var is absent or empty.
|
||||||
|
|
||||||
**Updating the surface** — when a new `#[tool]` fn is added to `AgentServer`
|
**Updating the surface** — when a new `#[tool]` fn is added to `HiveServer`
|
||||||
or `ManagerServer` in `hive-ag3nt/src/mcp.rs`, add its name to the matching
|
in `hive-ag3nt/src/mcp.rs`, add its name to the matching `ToolGroup::tools()`
|
||||||
`ToolGroup::tools()` slice in `hive-sh4re/src/lib.rs`. That's the single
|
slice in `hive-sh4re/src/lib.rs`. That's the single source of truth;
|
||||||
source of truth; `allowed_mcp_tools` reads it at session start.
|
`allowed_mcp_tools` reads it at session start.
|
||||||
|
|
||||||
## Capabilities
|
## Capabilities
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ async fn main() -> Result<()> {
|
||||||
serve_main::<ManagerSurface>(&cli.socket, poll_ms).await
|
serve_main::<ManagerSurface>(&cli.socket, poll_ms).await
|
||||||
}
|
}
|
||||||
(Role::Agent, Cmd::Mcp) => mcp::serve_agent_stdio(cli.socket).await,
|
(Role::Agent, Cmd::Mcp) => mcp::serve_agent_stdio(cli.socket).await,
|
||||||
(Role::Manager, Cmd::Mcp) => mcp::serve_manager_stdio(cli.socket).await,
|
(Role::Manager, Cmd::Mcp) => mcp::serve_agent_stdio(cli.socket).await,
|
||||||
(Role::Agent, Cmd::Wake { from, body }) => {
|
(Role::Agent, Cmd::Wake { from, body }) => {
|
||||||
wake::<AgentSurface>(&cli.socket, from, body).await
|
wake::<AgentSurface>(&cli.socket, from, body).await
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -345,6 +345,29 @@ async fn dispatch(req: &AgentRequest, agent: &str, coord: &Arc<Coordinator>) ->
|
||||||
Err(message) => AgentResponse::Err { message },
|
Err(message) => AgentResponse::Err { message },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AgentRequest::Start { name } => {
|
||||||
|
if !crate::topology::children_of(agent)
|
||||||
|
.iter()
|
||||||
|
.any(|c| c == name)
|
||||||
|
{
|
||||||
|
return AgentResponse::Err {
|
||||||
|
message: format!(
|
||||||
|
"agent `{agent}` cannot start `{name}`: \
|
||||||
|
not a direct child in the topology tree"
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
tracing::info!(%agent, %name, "agent: start child");
|
||||||
|
match crate::lifecycle::start(name).await {
|
||||||
|
Ok(()) => {
|
||||||
|
coord.kick_agent(name, "container started");
|
||||||
|
AgentResponse::Ok
|
||||||
|
}
|
||||||
|
Err(e) => AgentResponse::Err {
|
||||||
|
message: format!("{e:#}"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
AgentRequest::Restart { name } => {
|
AgentRequest::Restart { name } => {
|
||||||
// Topology check: the caller must be the direct parent of the
|
// Topology check: the caller must be the direct parent of the
|
||||||
// target. This is the only authorisation criterion — no
|
// target. This is the only authorisation criterion — no
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue