@openclaw/matrix 2026.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/index.ts +18 -0
- package/openclaw.plugin.json +11 -0
- package/package.json +36 -0
- package/src/actions.ts +185 -0
- package/src/channel.directory.test.ts +56 -0
- package/src/channel.ts +417 -0
- package/src/config-schema.ts +62 -0
- package/src/directory-live.ts +175 -0
- package/src/group-mentions.ts +61 -0
- package/src/matrix/accounts.test.ts +83 -0
- package/src/matrix/accounts.ts +63 -0
- package/src/matrix/actions/client.ts +53 -0
- package/src/matrix/actions/messages.ts +120 -0
- package/src/matrix/actions/pins.ts +70 -0
- package/src/matrix/actions/reactions.ts +84 -0
- package/src/matrix/actions/room.ts +88 -0
- package/src/matrix/actions/summary.ts +77 -0
- package/src/matrix/actions/types.ts +84 -0
- package/src/matrix/actions.ts +15 -0
- package/src/matrix/active-client.ts +11 -0
- package/src/matrix/client/config.ts +165 -0
- package/src/matrix/client/create-client.ts +127 -0
- package/src/matrix/client/logging.ts +35 -0
- package/src/matrix/client/runtime.ts +4 -0
- package/src/matrix/client/shared.ts +169 -0
- package/src/matrix/client/storage.ts +131 -0
- package/src/matrix/client/types.ts +34 -0
- package/src/matrix/client.test.ts +57 -0
- package/src/matrix/client.ts +9 -0
- package/src/matrix/credentials.ts +103 -0
- package/src/matrix/deps.ts +57 -0
- package/src/matrix/format.test.ts +34 -0
- package/src/matrix/format.ts +22 -0
- package/src/matrix/index.ts +11 -0
- package/src/matrix/monitor/allowlist.ts +58 -0
- package/src/matrix/monitor/auto-join.ts +68 -0
- package/src/matrix/monitor/direct.ts +105 -0
- package/src/matrix/monitor/events.ts +103 -0
- package/src/matrix/monitor/handler.ts +645 -0
- package/src/matrix/monitor/index.ts +279 -0
- package/src/matrix/monitor/location.ts +83 -0
- package/src/matrix/monitor/media.test.ts +103 -0
- package/src/matrix/monitor/media.ts +113 -0
- package/src/matrix/monitor/mentions.ts +31 -0
- package/src/matrix/monitor/replies.ts +96 -0
- package/src/matrix/monitor/room-info.ts +58 -0
- package/src/matrix/monitor/rooms.ts +43 -0
- package/src/matrix/monitor/threads.ts +64 -0
- package/src/matrix/monitor/types.ts +39 -0
- package/src/matrix/poll-types.test.ts +22 -0
- package/src/matrix/poll-types.ts +157 -0
- package/src/matrix/probe.ts +70 -0
- package/src/matrix/send/client.ts +63 -0
- package/src/matrix/send/formatting.ts +92 -0
- package/src/matrix/send/media.ts +220 -0
- package/src/matrix/send/targets.test.ts +102 -0
- package/src/matrix/send/targets.ts +144 -0
- package/src/matrix/send/types.ts +109 -0
- package/src/matrix/send.test.ts +172 -0
- package/src/matrix/send.ts +255 -0
- package/src/onboarding.ts +432 -0
- package/src/outbound.ts +53 -0
- package/src/resolve-targets.ts +89 -0
- package/src/runtime.ts +14 -0
- package/src/tool-actions.ts +160 -0
- package/src/types.ts +95 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
|
2
|
+
|
|
3
|
+
import type { CoreConfig } from "./types.js";
|
|
4
|
+
import {
|
|
5
|
+
deleteMatrixMessage,
|
|
6
|
+
editMatrixMessage,
|
|
7
|
+
getMatrixMemberInfo,
|
|
8
|
+
getMatrixRoomInfo,
|
|
9
|
+
listMatrixPins,
|
|
10
|
+
listMatrixReactions,
|
|
11
|
+
pinMatrixMessage,
|
|
12
|
+
readMatrixMessages,
|
|
13
|
+
removeMatrixReactions,
|
|
14
|
+
sendMatrixMessage,
|
|
15
|
+
unpinMatrixMessage,
|
|
16
|
+
} from "./matrix/actions.js";
|
|
17
|
+
import { reactMatrixMessage } from "./matrix/send.js";
|
|
18
|
+
import {
|
|
19
|
+
createActionGate,
|
|
20
|
+
jsonResult,
|
|
21
|
+
readNumberParam,
|
|
22
|
+
readReactionParams,
|
|
23
|
+
readStringParam,
|
|
24
|
+
} from "openclaw/plugin-sdk";
|
|
25
|
+
|
|
26
|
+
const messageActions = new Set(["sendMessage", "editMessage", "deleteMessage", "readMessages"]);
|
|
27
|
+
const reactionActions = new Set(["react", "reactions"]);
|
|
28
|
+
const pinActions = new Set(["pinMessage", "unpinMessage", "listPins"]);
|
|
29
|
+
|
|
30
|
+
function readRoomId(params: Record<string, unknown>, required = true): string {
|
|
31
|
+
const direct = readStringParam(params, "roomId") ?? readStringParam(params, "channelId");
|
|
32
|
+
if (direct) return direct;
|
|
33
|
+
if (!required) return readStringParam(params, "to") ?? "";
|
|
34
|
+
return readStringParam(params, "to", { required: true });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function handleMatrixAction(
|
|
38
|
+
params: Record<string, unknown>,
|
|
39
|
+
cfg: CoreConfig,
|
|
40
|
+
): Promise<AgentToolResult<unknown>> {
|
|
41
|
+
const action = readStringParam(params, "action", { required: true });
|
|
42
|
+
const isActionEnabled = createActionGate(cfg.channels?.matrix?.actions);
|
|
43
|
+
|
|
44
|
+
if (reactionActions.has(action)) {
|
|
45
|
+
if (!isActionEnabled("reactions")) {
|
|
46
|
+
throw new Error("Matrix reactions are disabled.");
|
|
47
|
+
}
|
|
48
|
+
const roomId = readRoomId(params);
|
|
49
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
50
|
+
if (action === "react") {
|
|
51
|
+
const { emoji, remove, isEmpty } = readReactionParams(params, {
|
|
52
|
+
removeErrorMessage: "Emoji is required to remove a Matrix reaction.",
|
|
53
|
+
});
|
|
54
|
+
if (remove || isEmpty) {
|
|
55
|
+
const result = await removeMatrixReactions(roomId, messageId, {
|
|
56
|
+
emoji: remove ? emoji : undefined,
|
|
57
|
+
});
|
|
58
|
+
return jsonResult({ ok: true, removed: result.removed });
|
|
59
|
+
}
|
|
60
|
+
await reactMatrixMessage(roomId, messageId, emoji);
|
|
61
|
+
return jsonResult({ ok: true, added: emoji });
|
|
62
|
+
}
|
|
63
|
+
const reactions = await listMatrixReactions(roomId, messageId);
|
|
64
|
+
return jsonResult({ ok: true, reactions });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (messageActions.has(action)) {
|
|
68
|
+
if (!isActionEnabled("messages")) {
|
|
69
|
+
throw new Error("Matrix messages are disabled.");
|
|
70
|
+
}
|
|
71
|
+
switch (action) {
|
|
72
|
+
case "sendMessage": {
|
|
73
|
+
const to = readStringParam(params, "to", { required: true });
|
|
74
|
+
const content = readStringParam(params, "content", {
|
|
75
|
+
required: true,
|
|
76
|
+
allowEmpty: true,
|
|
77
|
+
});
|
|
78
|
+
const mediaUrl = readStringParam(params, "mediaUrl");
|
|
79
|
+
const replyToId = readStringParam(params, "replyToId") ?? readStringParam(params, "replyTo");
|
|
80
|
+
const threadId = readStringParam(params, "threadId");
|
|
81
|
+
const result = await sendMatrixMessage(to, content, {
|
|
82
|
+
mediaUrl: mediaUrl ?? undefined,
|
|
83
|
+
replyToId: replyToId ?? undefined,
|
|
84
|
+
threadId: threadId ?? undefined,
|
|
85
|
+
});
|
|
86
|
+
return jsonResult({ ok: true, result });
|
|
87
|
+
}
|
|
88
|
+
case "editMessage": {
|
|
89
|
+
const roomId = readRoomId(params);
|
|
90
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
91
|
+
const content = readStringParam(params, "content", { required: true });
|
|
92
|
+
const result = await editMatrixMessage(roomId, messageId, content);
|
|
93
|
+
return jsonResult({ ok: true, result });
|
|
94
|
+
}
|
|
95
|
+
case "deleteMessage": {
|
|
96
|
+
const roomId = readRoomId(params);
|
|
97
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
98
|
+
const reason = readStringParam(params, "reason");
|
|
99
|
+
await deleteMatrixMessage(roomId, messageId, { reason: reason ?? undefined });
|
|
100
|
+
return jsonResult({ ok: true, deleted: true });
|
|
101
|
+
}
|
|
102
|
+
case "readMessages": {
|
|
103
|
+
const roomId = readRoomId(params);
|
|
104
|
+
const limit = readNumberParam(params, "limit", { integer: true });
|
|
105
|
+
const before = readStringParam(params, "before");
|
|
106
|
+
const after = readStringParam(params, "after");
|
|
107
|
+
const result = await readMatrixMessages(roomId, {
|
|
108
|
+
limit: limit ?? undefined,
|
|
109
|
+
before: before ?? undefined,
|
|
110
|
+
after: after ?? undefined,
|
|
111
|
+
});
|
|
112
|
+
return jsonResult({ ok: true, ...result });
|
|
113
|
+
}
|
|
114
|
+
default:
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (pinActions.has(action)) {
|
|
120
|
+
if (!isActionEnabled("pins")) {
|
|
121
|
+
throw new Error("Matrix pins are disabled.");
|
|
122
|
+
}
|
|
123
|
+
const roomId = readRoomId(params);
|
|
124
|
+
if (action === "pinMessage") {
|
|
125
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
126
|
+
const result = await pinMatrixMessage(roomId, messageId);
|
|
127
|
+
return jsonResult({ ok: true, pinned: result.pinned });
|
|
128
|
+
}
|
|
129
|
+
if (action === "unpinMessage") {
|
|
130
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
131
|
+
const result = await unpinMatrixMessage(roomId, messageId);
|
|
132
|
+
return jsonResult({ ok: true, pinned: result.pinned });
|
|
133
|
+
}
|
|
134
|
+
const result = await listMatrixPins(roomId);
|
|
135
|
+
return jsonResult({ ok: true, pinned: result.pinned, events: result.events });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (action === "memberInfo") {
|
|
139
|
+
if (!isActionEnabled("memberInfo")) {
|
|
140
|
+
throw new Error("Matrix member info is disabled.");
|
|
141
|
+
}
|
|
142
|
+
const userId = readStringParam(params, "userId", { required: true });
|
|
143
|
+
const roomId = readStringParam(params, "roomId") ?? readStringParam(params, "channelId");
|
|
144
|
+
const result = await getMatrixMemberInfo(userId, {
|
|
145
|
+
roomId: roomId ?? undefined,
|
|
146
|
+
});
|
|
147
|
+
return jsonResult({ ok: true, member: result });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (action === "channelInfo") {
|
|
151
|
+
if (!isActionEnabled("channelInfo")) {
|
|
152
|
+
throw new Error("Matrix room info is disabled.");
|
|
153
|
+
}
|
|
154
|
+
const roomId = readRoomId(params);
|
|
155
|
+
const result = await getMatrixRoomInfo(roomId);
|
|
156
|
+
return jsonResult({ ok: true, room: result });
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
throw new Error(`Unsupported Matrix action: ${action}`);
|
|
160
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export type ReplyToMode = "off" | "first" | "all";
|
|
2
|
+
export type GroupPolicy = "open" | "disabled" | "allowlist";
|
|
3
|
+
export type DmPolicy = "pairing" | "allowlist" | "open" | "disabled";
|
|
4
|
+
|
|
5
|
+
export type MatrixDmConfig = {
|
|
6
|
+
/** If false, ignore all incoming Matrix DMs. Default: true. */
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
/** Direct message access policy (default: pairing). */
|
|
9
|
+
policy?: DmPolicy;
|
|
10
|
+
/** Allowlist for DM senders (matrix user IDs, localparts, or "*"). */
|
|
11
|
+
allowFrom?: Array<string | number>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type MatrixRoomConfig = {
|
|
15
|
+
/** If false, disable the bot in this room (alias for allow: false). */
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
/** Legacy room allow toggle; prefer enabled. */
|
|
18
|
+
allow?: boolean;
|
|
19
|
+
/** Require mentioning the bot to trigger replies. */
|
|
20
|
+
requireMention?: boolean;
|
|
21
|
+
/** Optional tool policy overrides for this room. */
|
|
22
|
+
tools?: { allow?: string[]; deny?: string[] };
|
|
23
|
+
/** If true, reply without mention requirements. */
|
|
24
|
+
autoReply?: boolean;
|
|
25
|
+
/** Optional allowlist for room senders (user IDs or localparts). */
|
|
26
|
+
users?: Array<string | number>;
|
|
27
|
+
/** Optional skill filter for this room. */
|
|
28
|
+
skills?: string[];
|
|
29
|
+
/** Optional system prompt snippet for this room. */
|
|
30
|
+
systemPrompt?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type MatrixActionConfig = {
|
|
34
|
+
reactions?: boolean;
|
|
35
|
+
messages?: boolean;
|
|
36
|
+
pins?: boolean;
|
|
37
|
+
memberInfo?: boolean;
|
|
38
|
+
channelInfo?: boolean;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type MatrixConfig = {
|
|
42
|
+
/** Optional display name for this account (used in CLI/UI lists). */
|
|
43
|
+
name?: string;
|
|
44
|
+
/** If false, do not start Matrix. Default: true. */
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
/** Matrix homeserver URL (https://matrix.example.org). */
|
|
47
|
+
homeserver?: string;
|
|
48
|
+
/** Matrix user id (@user:server). */
|
|
49
|
+
userId?: string;
|
|
50
|
+
/** Matrix access token. */
|
|
51
|
+
accessToken?: string;
|
|
52
|
+
/** Matrix password (used only to fetch access token). */
|
|
53
|
+
password?: string;
|
|
54
|
+
/** Optional device name when logging in via password. */
|
|
55
|
+
deviceName?: string;
|
|
56
|
+
/** Initial sync limit for startup (default: @vector-im/matrix-bot-sdk default). */
|
|
57
|
+
initialSyncLimit?: number;
|
|
58
|
+
/** Enable end-to-end encryption (E2EE). Default: false. */
|
|
59
|
+
encryption?: boolean;
|
|
60
|
+
/** If true, enforce allowlists for groups + DMs regardless of policy. */
|
|
61
|
+
allowlistOnly?: boolean;
|
|
62
|
+
/** Group message policy (default: allowlist). */
|
|
63
|
+
groupPolicy?: GroupPolicy;
|
|
64
|
+
/** Allowlist for group senders (user IDs or localparts). */
|
|
65
|
+
groupAllowFrom?: Array<string | number>;
|
|
66
|
+
/** Control reply threading when reply tags are present (off|first|all). */
|
|
67
|
+
replyToMode?: ReplyToMode;
|
|
68
|
+
/** How to handle thread replies (off|inbound|always). */
|
|
69
|
+
threadReplies?: "off" | "inbound" | "always";
|
|
70
|
+
/** Outbound text chunk size (chars). Default: 4000. */
|
|
71
|
+
textChunkLimit?: number;
|
|
72
|
+
/** Chunking mode: "length" (default) splits by size; "newline" splits on every newline. */
|
|
73
|
+
chunkMode?: "length" | "newline";
|
|
74
|
+
/** Max outbound media size in MB. */
|
|
75
|
+
mediaMaxMb?: number;
|
|
76
|
+
/** Auto-join invites (always|allowlist|off). Default: always. */
|
|
77
|
+
autoJoin?: "always" | "allowlist" | "off";
|
|
78
|
+
/** Allowlist for auto-join invites (room IDs, aliases). */
|
|
79
|
+
autoJoinAllowlist?: Array<string | number>;
|
|
80
|
+
/** Direct message policy + allowlist overrides. */
|
|
81
|
+
dm?: MatrixDmConfig;
|
|
82
|
+
/** Room config allowlist keyed by room ID, alias, or name. */
|
|
83
|
+
groups?: Record<string, MatrixRoomConfig>;
|
|
84
|
+
/** Room config allowlist keyed by room ID, alias, or name. Legacy; use groups. */
|
|
85
|
+
rooms?: Record<string, MatrixRoomConfig>;
|
|
86
|
+
/** Per-action tool gating (default: true for all). */
|
|
87
|
+
actions?: MatrixActionConfig;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type CoreConfig = {
|
|
91
|
+
channels?: {
|
|
92
|
+
matrix?: MatrixConfig;
|
|
93
|
+
};
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
};
|