feat(#2039): list matrix identities in get_agent_meta
This commit is contained in:
parent
52de0ca648
commit
5b442796ca
3 changed files with 59 additions and 0 deletions
|
|
@ -58,6 +58,7 @@ pub enum SocketReply {
|
||||||
status_set_at: Option<i64>,
|
status_set_at: Option<i64>,
|
||||||
hive_name: Option<String>,
|
hive_name: Option<String>,
|
||||||
swarm_name: Option<String>,
|
swarm_name: Option<String>,
|
||||||
|
matrix_accounts: Vec<hive_sh4re::MatrixIdentity>,
|
||||||
},
|
},
|
||||||
/// `create_repo` result — the new repo's full name + clone URL.
|
/// `create_repo` result — the new repo's full name + clone URL.
|
||||||
RepoCreated {
|
RepoCreated {
|
||||||
|
|
@ -109,6 +110,7 @@ impl From<hive_sh4re::Response> for SocketReply {
|
||||||
status_set_at,
|
status_set_at,
|
||||||
hive_name,
|
hive_name,
|
||||||
swarm_name,
|
swarm_name,
|
||||||
|
matrix_accounts,
|
||||||
} => Self::AgentMeta {
|
} => Self::AgentMeta {
|
||||||
name,
|
name,
|
||||||
running,
|
running,
|
||||||
|
|
@ -117,6 +119,7 @@ impl From<hive_sh4re::Response> for SocketReply {
|
||||||
status_set_at,
|
status_set_at,
|
||||||
hive_name,
|
hive_name,
|
||||||
swarm_name,
|
swarm_name,
|
||||||
|
matrix_accounts,
|
||||||
},
|
},
|
||||||
hive_sh4re::Response::RepoCreated {
|
hive_sh4re::Response::RepoCreated {
|
||||||
full_name,
|
full_name,
|
||||||
|
|
@ -452,6 +455,7 @@ pub fn format_agent_meta(resp: Result<SocketReply, anyhow::Error>) -> String {
|
||||||
status_set_at,
|
status_set_at,
|
||||||
hive_name,
|
hive_name,
|
||||||
swarm_name,
|
swarm_name,
|
||||||
|
matrix_accounts,
|
||||||
}) => {
|
}) => {
|
||||||
let rev = hyperhive_rev.as_deref().unwrap_or("<unknown>");
|
let rev = hyperhive_rev.as_deref().unwrap_or("<unknown>");
|
||||||
let run = if running { "yes" } else { "no" };
|
let run = if running { "yes" } else { "no" };
|
||||||
|
|
@ -498,6 +502,22 @@ pub fn format_agent_meta(resp: Result<SocketReply, anyhow::Error>) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Matrix identities the agent can act as (the `account` arg on
|
||||||
|
// the matrix tools). Listed only when matrix is provisioned, so
|
||||||
|
// non-matrix agents don't see an empty line.
|
||||||
|
if !matrix_accounts.is_empty() {
|
||||||
|
use std::fmt::Write as _;
|
||||||
|
out.push_str("\nmatrix_accounts:");
|
||||||
|
for acct in &matrix_accounts {
|
||||||
|
let uid = acct.user_id.as_deref().unwrap_or("?");
|
||||||
|
let primary = if acct.is_primary { " [primary]" } else { "" };
|
||||||
|
let _ = write!(
|
||||||
|
out,
|
||||||
|
"\n {} ({uid}) on {}{primary}",
|
||||||
|
acct.name, acct.homeserver
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
Ok(SocketReply::Err(m)) => format!("get_agent_meta failed: {m}"),
|
Ok(SocketReply::Err(m)) => format!("get_agent_meta failed: {m}"),
|
||||||
|
|
|
||||||
|
|
@ -417,9 +417,24 @@ async fn handle_get_agent_meta(
|
||||||
status_set_at,
|
status_set_at,
|
||||||
hive_name,
|
hive_name,
|
||||||
swarm_name,
|
swarm_name,
|
||||||
|
matrix_accounts: read_agent_matrix_identities(target),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the target agent's matrix identities from the daemon's
|
||||||
|
/// `matrix-accounts.json` snapshot (under the agent's state dir).
|
||||||
|
/// Best-effort: an absent / unparseable snapshot (no matrix provisioning,
|
||||||
|
/// or the daemon not up yet) yields an empty list. The `MatrixIdentity`
|
||||||
|
/// serde shape matches the snapshot entries; the snapshot's `live` field is
|
||||||
|
/// ignored (only live accounts are written).
|
||||||
|
fn read_agent_matrix_identities(agent: &str) -> Vec<hive_sh4re::MatrixIdentity> {
|
||||||
|
let path = Coordinator::agent_notes_dir(agent).join("matrix-accounts.json");
|
||||||
|
std::fs::read_to_string(&path)
|
||||||
|
.ok()
|
||||||
|
.and_then(|s| serde_json::from_str::<Vec<hive_sh4re::MatrixIdentity>>(&s).ok())
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
/// `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_sh4re::Response {
|
fn handle_status(coord: &Arc<Coordinator>, agent: &str) -> hive_sh4re::Response {
|
||||||
match coord.broker.count_pending(agent) {
|
match coord.broker.count_pending(agent) {
|
||||||
|
|
|
||||||
|
|
@ -845,6 +845,10 @@ pub enum Response {
|
||||||
hive_name: Option<String>,
|
hive_name: Option<String>,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
swarm_name: Option<String>,
|
swarm_name: Option<String>,
|
||||||
|
/// Matrix identities this agent can act as (one per configured +
|
||||||
|
/// live account). Empty for agents with no matrix provisioning.
|
||||||
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
matrix_accounts: Vec<MatrixIdentity>,
|
||||||
},
|
},
|
||||||
/// `GetLogs` result: journal lines for the requested container.
|
/// `GetLogs` result: journal lines for the requested container.
|
||||||
/// Returned on the manager socket only.
|
/// Returned on the manager socket only.
|
||||||
|
|
@ -918,6 +922,26 @@ pub struct AgentStatusRow {
|
||||||
pub parent: Option<String>,
|
pub parent: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// One matrix identity an agent can act as, surfaced in `GetAgentMeta`'s
|
||||||
|
/// `matrix_accounts`. Field names match the daemon's `matrix-accounts.json`
|
||||||
|
/// snapshot (written by `hive-matrix-mcp`'s account registry) so hive-c0re
|
||||||
|
/// deserializes the snapshot straight into `Vec<MatrixIdentity>`; the
|
||||||
|
/// snapshot's `live` field is ignored here (only live accounts are listed).
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct MatrixIdentity {
|
||||||
|
/// Logical account name (the `account` arg on the matrix MCP tools).
|
||||||
|
pub name: String,
|
||||||
|
/// Matrix user id (`@user:server`). `None` if the session restored
|
||||||
|
/// without a known user id yet.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub user_id: Option<String>,
|
||||||
|
/// Homeserver base URL this account is on.
|
||||||
|
pub homeserver: String,
|
||||||
|
/// Whether this is the primary account (selected when a matrix tool
|
||||||
|
/// call omits `account`).
|
||||||
|
pub is_primary: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// Serde default for the `running` field; keeps wire backwards-compat
|
/// Serde default for the `running` field; keeps wire backwards-compat
|
||||||
/// with pre-running-field payloads. See
|
/// with pre-running-field payloads. See
|
||||||
/// `docs/conventions.md::Agent metadata`.
|
/// `docs/conventions.md::Agent metadata`.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue