type get_agent_meta target as Ident (#2621)
This commit is contained in:
parent
3df565789c
commit
8c1979f05c
3 changed files with 32 additions and 27 deletions
|
|
@ -392,8 +392,12 @@ impl AgentServer {
|
||||||
async fn get_agent_meta(&self, Parameters(args): Parameters<GetAgentMetaArgs>) -> String {
|
async fn get_agent_meta(&self, Parameters(args): Parameters<GetAgentMetaArgs>) -> String {
|
||||||
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 name = match args.name.map(|n| hive_types::Ident::parse(&n)).transpose() {
|
||||||
|
Ok(name) => name,
|
||||||
|
Err(reason) => return format!("invalid agent name: {reason}"),
|
||||||
|
};
|
||||||
let (resp, retries) = self
|
let (resp, retries) = self
|
||||||
.dispatch(hive_core_agent_sock::Request::GetAgentMeta { name: args.name })
|
.dispatch(hive_core_agent_sock::Request::GetAgentMeta { name })
|
||||||
.await;
|
.await;
|
||||||
annotate_retries(format_agent_meta(resp), retries)
|
annotate_retries(format_agent_meta(resp), retries)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ pub(crate) async fn dispatch_shared(
|
||||||
} => handle_remind(coord, agent, message, timing, file_path.as_deref()),
|
} => handle_remind(coord, agent, message, timing, file_path.as_deref()),
|
||||||
hive_core_agent_sock::Request::SetStatus { text } => handle_set_status(coord, text),
|
hive_core_agent_sock::Request::SetStatus { text } => handle_set_status(coord, text),
|
||||||
hive_core_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_ref()).await
|
||||||
}
|
}
|
||||||
hive_core_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(
|
||||||
|
|
@ -418,42 +418,43 @@ async fn handle_create_repo(agent: &str, repo: &str) -> hive_core_agent_sock::Re
|
||||||
async fn handle_get_agent_meta(
|
async fn handle_get_agent_meta(
|
||||||
coord: &Arc<Coordinator>,
|
coord: &Arc<Coordinator>,
|
||||||
agent: &str,
|
agent: &str,
|
||||||
name: Option<&str>,
|
name: Option<&hive_types::Ident>,
|
||||||
) -> hive_core_agent_sock::Response {
|
) -> hive_core_agent_sock::Response {
|
||||||
let target = name.unwrap_or(agent);
|
// `name` arrives pre-validated by serde (wire field is `Ident`). The
|
||||||
// `name` is agent-supplied and flows into filesystem reads below
|
// `None` default (target == caller) still needs a parse since `agent`
|
||||||
// (`read_agent_status_live`, `read_agent_matrix_identities` →
|
// is a plain `&str` here — but it's the caller's own authenticated
|
||||||
// `agent_notes_dir(target)`), where a `../` component would traverse at
|
// name, already valid in practice.
|
||||||
// the OS level. Validate it before any path is built. The `None` default
|
let target_id = match name {
|
||||||
// (`target == agent`) is the caller's own authenticated name, already
|
Some(id) => id.clone(),
|
||||||
// valid — but validating unconditionally is simplest and harmless.
|
None => match hive_types::Ident::parse(agent) {
|
||||||
let target_id = match hive_types::Ident::parse(target) {
|
Ok(id) => id,
|
||||||
Ok(id) => id,
|
Err(reason) => {
|
||||||
Err(reason) => {
|
return hive_core_agent_sock::Response::Err {
|
||||||
return hive_core_agent_sock::Response::Err {
|
message: format!("get_agent_meta: invalid agent name {agent:?}: {reason}"),
|
||||||
message: format!("get_agent_meta: invalid agent name {target:?}: {reason}"),
|
};
|
||||||
};
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
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();
|
||||||
|
// Matrix identities are public handles (`name` / `user_id`
|
||||||
|
// `@user:server` / `homeserver`) — the access token lives separately
|
||||||
|
// in the agent's `matrix-token` and is never part of this response.
|
||||||
|
// Peer visibility is intentional: it lets an agent verify/contact
|
||||||
|
// another on a public matrix instance. The `Ident::parse` gate
|
||||||
|
// above is what closes the real vector here (path traversal via `../`
|
||||||
|
// in an agent-supplied name).
|
||||||
|
let matrix_accounts = read_agent_matrix_identities(&target_id);
|
||||||
hive_core_agent_sock::Response::AgentMeta {
|
hive_core_agent_sock::Response::AgentMeta {
|
||||||
name: target.to_owned(),
|
name: target_id.into_string(),
|
||||||
running,
|
running,
|
||||||
hyperhive_rev: crate::auto_update::current_flake_rev(&coord.hyperhive_flake),
|
hyperhive_rev: crate::auto_update::current_flake_rev(&coord.hyperhive_flake),
|
||||||
status_text,
|
status_text,
|
||||||
status_set_at,
|
status_set_at,
|
||||||
hive_name,
|
hive_name,
|
||||||
swarm_name,
|
swarm_name,
|
||||||
// Matrix identities are public handles (`name` / `user_id`
|
matrix_accounts,
|
||||||
// `@user:server` / `homeserver`) — the access token lives separately
|
|
||||||
// in the agent's `matrix-token` and is never part of this response.
|
|
||||||
// Peer visibility is intentional: it lets an agent verify/contact
|
|
||||||
// another on a public matrix instance. The `Ident::parse` gate
|
|
||||||
// above is what closes the real vector here (path traversal via `../`
|
|
||||||
// in an agent-supplied name).
|
|
||||||
matrix_accounts: read_agent_matrix_identities(&target_id),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ pub enum Request {
|
||||||
/// `docs/conventions.md::Agent metadata`.
|
/// `docs/conventions.md::Agent metadata`.
|
||||||
GetAgentMeta {
|
GetAgentMeta {
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
name: Option<String>,
|
name: Option<Ident>,
|
||||||
},
|
},
|
||||||
/// Cancel an open thread the agent owns. Authorisation +
|
/// Cancel an open thread the agent owns. Authorisation +
|
||||||
/// per-kind semantics in
|
/// per-kind semantics in
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue