feat(#1681): add matrix send_file + send_file_dm tools

This commit is contained in:
damocles 2026-06-15 17:02:30 +02:00 committed by mara
commit cbbd6f3d6e
6 changed files with 218 additions and 20 deletions

View file

@ -79,6 +79,32 @@ struct SendDmArgs {
body: String,
}
#[derive(Debug, Deserialize, JsonSchema)]
struct SendFileArgs {
/// Matrix room id (`!abc:server`) or canonical alias (`#name:server`).
room: String,
/// Absolute path to a local file readable by the agent (e.g. a built
/// PDF under the agent's workspace). MIME type is inferred from the
/// extension. 50 MiB cap.
path: String,
/// Optional caption, sent as a follow-up text message in the room.
#[serde(default)]
caption: Option<String>,
}
#[derive(Debug, Deserialize, JsonSchema)]
struct SendFileDmArgs {
/// Matrix user id of the recipient (`@user:server`). DM room is
/// created if one doesn't already exist.
user_id: String,
/// Absolute path to a local file readable by the agent. MIME type is
/// inferred from the extension. 50 MiB cap.
path: String,
/// Optional caption, sent as a follow-up text message in the DM.
#[serde(default)]
caption: Option<String>,
}
#[derive(Debug, Deserialize, JsonSchema)]
struct SendReactionArgs {
room: String,
@ -196,6 +222,42 @@ impl MatrixBridge {
)
}
#[tool(
description = "Upload a local file and post it as an attachment to a matrix \
room. `room` is a room id (!abc:server) or alias (#name:server); `path` \
is an absolute path to a local file (MIME inferred from extension, 50 MiB \
cap); optional `caption` is sent as a follow-up message. Rejected if the \
room has unread messages read_room then mark_read first."
)]
async fn send_file(&self, Parameters(args): Parameters<SendFileArgs>) -> String {
render(
round_trip(DaemonRequest::SendFile {
room: args.room,
path: args.path,
caption: args.caption,
})
.await,
)
}
#[tool(
description = "Open (or reuse) a DM with `user_id` (@user:server) and upload \
a local file as an attachment. `path` is an absolute local file path (MIME \
inferred, 50 MiB cap); optional `caption` is sent as a follow-up message. \
If the DM room already exists with unread messages, the send is rejected \
read_room then mark_read first."
)]
async fn send_file_dm(&self, Parameters(args): Parameters<SendFileDmArgs>) -> String {
render(
round_trip(DaemonRequest::SendFileDm {
user_id: args.user_id,
path: args.path,
caption: args.caption,
})
.await,
)
}
#[tool(
description = "React to a specific matrix event with an emoji or short \
string `key`. Matrix-spec annotation; renders as a reaction in \