feat: multi-account matrix daemon (account-routed mcp surface)
This commit is contained in:
parent
73c53c7d4a
commit
8e79eb4f26
7 changed files with 613 additions and 156 deletions
|
|
@ -27,13 +27,24 @@ use crate::{handlers, wake};
|
|||
/// `hyperhive_socket`. The wake body summarises ALL rooms with unread
|
||||
/// notifications at wake time (not just the triggering event) so the
|
||||
/// agent receives a full picture in one prompt.
|
||||
pub fn install_message_handler(client: &Client, hyperhive_socket: PathBuf) {
|
||||
///
|
||||
/// `account_tag` is `Some(name)` only in multi-account mode (N>1 matrix
|
||||
/// accounts on this daemon); when set it is prepended to the wake body
|
||||
/// so the agent knows which account to `read_room` on. In the
|
||||
/// single-account case it is `None` and the wake body is unchanged.
|
||||
pub fn install_message_handler(
|
||||
client: &Client,
|
||||
hyperhive_socket: PathBuf,
|
||||
account_tag: Option<String>,
|
||||
) {
|
||||
let socket = Arc::new(hyperhive_socket);
|
||||
let account_tag = Arc::new(account_tag);
|
||||
let own_user = client.user_id().map(std::borrow::ToOwned::to_owned);
|
||||
client.add_event_handler({
|
||||
let socket = socket.clone();
|
||||
move |event: OriginalSyncRoomMessageEvent, room: Room, client: Client| {
|
||||
let socket = socket.clone();
|
||||
let account_tag = account_tag.clone();
|
||||
let own_user = own_user.clone();
|
||||
async move {
|
||||
// INFO so the live host journal shows the handler actually
|
||||
|
|
@ -82,6 +93,7 @@ pub fn install_message_handler(client: &Client, hyperhive_socket: PathBuf) {
|
|||
} else {
|
||||
wake::format_unread_summary(&unread)
|
||||
};
|
||||
let body = wake::tag_account(account_tag.as_ref().as_deref(), body);
|
||||
if let Err(e) = wake::send_wake(&socket, &body).await {
|
||||
tracing::warn!(error = %e, "failed to deliver matrix wake to hyperhive");
|
||||
} else {
|
||||
|
|
@ -106,7 +118,12 @@ pub fn install_message_handler(client: &Client, hyperhive_socket: PathBuf) {
|
|||
/// than on every sync tick; it is pruned to the current invite set each
|
||||
/// pass so a withdrawn-then-reissued invite wakes again. The agent
|
||||
/// decides whether to accept or reject by calling `resolve_invite`.
|
||||
pub async fn sweep_invites(client: &Client, socket: &Path, notified: &Mutex<HashSet<OwnedRoomId>>) {
|
||||
pub async fn sweep_invites(
|
||||
client: &Client,
|
||||
socket: &Path,
|
||||
notified: &Mutex<HashSet<OwnedRoomId>>,
|
||||
account_tag: Option<&str>,
|
||||
) {
|
||||
let current = client.invited_rooms();
|
||||
let current_ids: HashSet<OwnedRoomId> =
|
||||
current.iter().map(|r| r.room_id().to_owned()).collect();
|
||||
|
|
@ -134,9 +151,12 @@ pub async fn sweep_invites(client: &Client, socket: &Path, notified: &Mutex<Hash
|
|||
let room_id = room.room_id().to_owned();
|
||||
let label = room.name().unwrap_or_else(|| room_id.to_string());
|
||||
tracing::info!(%room_id, "matrix: pending invite swept, waking agent");
|
||||
let body = format!(
|
||||
"[matrix] invited to {label} ({room_id}) — \
|
||||
use list_invites to see pending invites, resolve_invite to accept or reject"
|
||||
let body = wake::tag_account(
|
||||
account_tag,
|
||||
format!(
|
||||
"[matrix] invited to {label} ({room_id}) — \
|
||||
use list_invites to see pending invites, resolve_invite to accept or reject"
|
||||
),
|
||||
);
|
||||
if let Err(e) = wake::send_wake(socket, &body).await {
|
||||
tracing::warn!(error = %e, "matrix: failed to deliver invite-wake to hyperhive");
|
||||
|
|
|
|||
Loading…
Reference in a new issue