@badgerclaw/connect 1.0.0
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 +104 -0
- package/SETUP.md +131 -0
- package/index.ts +23 -0
- package/openclaw.plugin.json +1 -0
- package/package.json +32 -0
- package/src/actions.ts +195 -0
- package/src/channel.ts +461 -0
- package/src/config-schema.ts +62 -0
- package/src/connect.ts +17 -0
- package/src/directory-live.ts +209 -0
- package/src/group-mentions.ts +52 -0
- package/src/matrix/accounts.ts +114 -0
- package/src/matrix/actions/client.ts +47 -0
- package/src/matrix/actions/limits.ts +6 -0
- package/src/matrix/actions/messages.ts +126 -0
- package/src/matrix/actions/pins.ts +84 -0
- package/src/matrix/actions/reactions.ts +102 -0
- package/src/matrix/actions/room.ts +85 -0
- package/src/matrix/actions/summary.ts +75 -0
- package/src/matrix/actions/types.ts +85 -0
- package/src/matrix/actions.ts +15 -0
- package/src/matrix/active-client.ts +32 -0
- package/src/matrix/client/config.ts +245 -0
- package/src/matrix/client/create-client.ts +125 -0
- package/src/matrix/client/logging.ts +46 -0
- package/src/matrix/client/runtime.ts +4 -0
- package/src/matrix/client/shared.ts +210 -0
- package/src/matrix/client/startup.ts +29 -0
- package/src/matrix/client/storage.ts +131 -0
- package/src/matrix/client/types.ts +34 -0
- package/src/matrix/client-bootstrap.ts +47 -0
- package/src/matrix/client.ts +14 -0
- package/src/matrix/credentials.ts +125 -0
- package/src/matrix/deps.ts +126 -0
- package/src/matrix/format.ts +22 -0
- package/src/matrix/index.ts +11 -0
- package/src/matrix/monitor/access-policy.ts +126 -0
- package/src/matrix/monitor/allowlist.ts +94 -0
- package/src/matrix/monitor/auto-join.ts +72 -0
- package/src/matrix/monitor/direct.ts +152 -0
- package/src/matrix/monitor/events.ts +168 -0
- package/src/matrix/monitor/handler.ts +768 -0
- package/src/matrix/monitor/inbound-body.ts +28 -0
- package/src/matrix/monitor/index.ts +414 -0
- package/src/matrix/monitor/location.ts +100 -0
- package/src/matrix/monitor/media.ts +118 -0
- package/src/matrix/monitor/mentions.ts +62 -0
- package/src/matrix/monitor/replies.ts +124 -0
- package/src/matrix/monitor/room-info.ts +55 -0
- package/src/matrix/monitor/rooms.ts +47 -0
- package/src/matrix/monitor/threads.ts +68 -0
- package/src/matrix/monitor/types.ts +39 -0
- package/src/matrix/poll-types.ts +167 -0
- package/src/matrix/probe.ts +69 -0
- package/src/matrix/sdk-runtime.ts +18 -0
- package/src/matrix/send/client.ts +99 -0
- package/src/matrix/send/formatting.ts +93 -0
- package/src/matrix/send/media.ts +230 -0
- package/src/matrix/send/targets.ts +150 -0
- package/src/matrix/send/types.ts +110 -0
- package/src/matrix/send-queue.ts +28 -0
- package/src/matrix/send.ts +267 -0
- package/src/onboarding.ts +331 -0
- package/src/outbound.ts +58 -0
- package/src/resolve-targets.ts +125 -0
- package/src/runtime.ts +6 -0
- package/src/secret-input.ts +13 -0
- package/src/test-mocks.ts +53 -0
- package/src/tool-actions.ts +164 -0
- package/src/types.ts +118 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { mapAllowlistResolutionInputs } from "openclaw/plugin-sdk/compat";
|
|
2
|
+
import type {
|
|
3
|
+
ChannelDirectoryEntry,
|
|
4
|
+
ChannelResolveKind,
|
|
5
|
+
ChannelResolveResult,
|
|
6
|
+
RuntimeEnv,
|
|
7
|
+
} from "openclaw/plugin-sdk/matrix";
|
|
8
|
+
import { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js";
|
|
9
|
+
|
|
10
|
+
function findExactDirectoryMatches(
|
|
11
|
+
matches: ChannelDirectoryEntry[],
|
|
12
|
+
query: string,
|
|
13
|
+
): ChannelDirectoryEntry[] {
|
|
14
|
+
const normalized = query.trim().toLowerCase();
|
|
15
|
+
if (!normalized) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
return matches.filter((match) => {
|
|
19
|
+
const id = match.id.trim().toLowerCase();
|
|
20
|
+
const name = match.name?.trim().toLowerCase();
|
|
21
|
+
const handle = match.handle?.trim().toLowerCase();
|
|
22
|
+
return normalized === id || normalized === name || normalized === handle;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function pickBestGroupMatch(
|
|
27
|
+
matches: ChannelDirectoryEntry[],
|
|
28
|
+
query: string,
|
|
29
|
+
): ChannelDirectoryEntry | undefined {
|
|
30
|
+
if (matches.length === 0) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const [exact] = findExactDirectoryMatches(matches, query);
|
|
34
|
+
return exact ?? matches[0];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function pickBestUserMatch(
|
|
38
|
+
matches: ChannelDirectoryEntry[],
|
|
39
|
+
query: string,
|
|
40
|
+
): ChannelDirectoryEntry | undefined {
|
|
41
|
+
if (matches.length === 0) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const exact = findExactDirectoryMatches(matches, query);
|
|
45
|
+
if (exact.length === 1) {
|
|
46
|
+
return exact[0];
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function describeUserMatchFailure(matches: ChannelDirectoryEntry[], query: string): string {
|
|
52
|
+
if (matches.length === 0) {
|
|
53
|
+
return "no matches";
|
|
54
|
+
}
|
|
55
|
+
const normalized = query.trim().toLowerCase();
|
|
56
|
+
if (!normalized) {
|
|
57
|
+
return "empty input";
|
|
58
|
+
}
|
|
59
|
+
const exact = findExactDirectoryMatches(matches, normalized);
|
|
60
|
+
if (exact.length === 0) {
|
|
61
|
+
return "no exact match; use full BadgerClaw ID";
|
|
62
|
+
}
|
|
63
|
+
if (exact.length > 1) {
|
|
64
|
+
return "multiple exact matches; use full BadgerClaw ID";
|
|
65
|
+
}
|
|
66
|
+
return "no exact match; use full BadgerClaw ID";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function resolveMatrixTargets(params: {
|
|
70
|
+
cfg: unknown;
|
|
71
|
+
inputs: string[];
|
|
72
|
+
kind: ChannelResolveKind;
|
|
73
|
+
runtime?: RuntimeEnv;
|
|
74
|
+
}): Promise<ChannelResolveResult[]> {
|
|
75
|
+
return await mapAllowlistResolutionInputs({
|
|
76
|
+
inputs: params.inputs,
|
|
77
|
+
mapInput: async (input): Promise<ChannelResolveResult> => {
|
|
78
|
+
const trimmed = input.trim();
|
|
79
|
+
if (!trimmed) {
|
|
80
|
+
return { input, resolved: false, note: "empty input" };
|
|
81
|
+
}
|
|
82
|
+
if (params.kind === "user") {
|
|
83
|
+
if (trimmed.startsWith("@") && trimmed.includes(":")) {
|
|
84
|
+
return { input, resolved: true, id: trimmed };
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const matches = await listMatrixDirectoryPeersLive({
|
|
88
|
+
cfg: params.cfg,
|
|
89
|
+
query: trimmed,
|
|
90
|
+
limit: 5,
|
|
91
|
+
});
|
|
92
|
+
const best = pickBestUserMatch(matches, trimmed);
|
|
93
|
+
return {
|
|
94
|
+
input,
|
|
95
|
+
resolved: Boolean(best?.id),
|
|
96
|
+
id: best?.id,
|
|
97
|
+
name: best?.name,
|
|
98
|
+
note: best ? undefined : describeUserMatchFailure(matches, trimmed),
|
|
99
|
+
};
|
|
100
|
+
} catch (err) {
|
|
101
|
+
params.runtime?.error?.(`badgerclaw resolve failed: ${String(err)}`);
|
|
102
|
+
return { input, resolved: false, note: "lookup failed" };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const matches = await listMatrixDirectoryGroupsLive({
|
|
107
|
+
cfg: params.cfg,
|
|
108
|
+
query: trimmed,
|
|
109
|
+
limit: 5,
|
|
110
|
+
});
|
|
111
|
+
const best = pickBestGroupMatch(matches, trimmed);
|
|
112
|
+
return {
|
|
113
|
+
input,
|
|
114
|
+
resolved: Boolean(best?.id),
|
|
115
|
+
id: best?.id,
|
|
116
|
+
name: best?.name,
|
|
117
|
+
note: matches.length > 1 ? "multiple matches; chose first" : undefined,
|
|
118
|
+
};
|
|
119
|
+
} catch (err) {
|
|
120
|
+
params.runtime?.error?.(`badgerclaw resolve failed: ${String(err)}`);
|
|
121
|
+
return { input, resolved: false, note: "lookup failed" };
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
package/src/runtime.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/compat";
|
|
2
|
+
import type { PluginRuntime } from "openclaw/plugin-sdk/matrix";
|
|
3
|
+
|
|
4
|
+
const { setRuntime: setMatrixRuntime, getRuntime: getMatrixRuntime } =
|
|
5
|
+
createPluginRuntimeStore<PluginRuntime>("BadgerClaw runtime not initialized");
|
|
6
|
+
export { getMatrixRuntime, setMatrixRuntime };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildSecretInputSchema,
|
|
3
|
+
hasConfiguredSecretInput,
|
|
4
|
+
normalizeResolvedSecretInputString,
|
|
5
|
+
normalizeSecretInputString,
|
|
6
|
+
} from "openclaw/plugin-sdk/matrix";
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
buildSecretInputSchema,
|
|
10
|
+
hasConfiguredSecretInput,
|
|
11
|
+
normalizeResolvedSecretInputString,
|
|
12
|
+
normalizeSecretInputString,
|
|
13
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Mock } from "vitest";
|
|
2
|
+
import { vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
type MatrixBotSdkMockParams = {
|
|
5
|
+
matrixClient?: unknown;
|
|
6
|
+
simpleFsStorageProvider?: unknown;
|
|
7
|
+
rustSdkCryptoStorageProvider?: unknown;
|
|
8
|
+
includeVerboseLogService?: boolean;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type MatrixBotSdkMock = {
|
|
12
|
+
ConsoleLogger: new () => {
|
|
13
|
+
trace: Mock<() => void>;
|
|
14
|
+
debug: Mock<() => void>;
|
|
15
|
+
info: Mock<() => void>;
|
|
16
|
+
warn: Mock<() => void>;
|
|
17
|
+
error: Mock<() => void>;
|
|
18
|
+
};
|
|
19
|
+
MatrixClient: unknown;
|
|
20
|
+
LogService: {
|
|
21
|
+
setLogger: Mock<() => void>;
|
|
22
|
+
warn?: Mock<() => void>;
|
|
23
|
+
info?: Mock<() => void>;
|
|
24
|
+
debug?: Mock<() => void>;
|
|
25
|
+
};
|
|
26
|
+
SimpleFsStorageProvider: unknown;
|
|
27
|
+
RustSdkCryptoStorageProvider: unknown;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export function createMatrixBotSdkMock(params: MatrixBotSdkMockParams = {}): MatrixBotSdkMock {
|
|
31
|
+
return {
|
|
32
|
+
ConsoleLogger: class {
|
|
33
|
+
trace = vi.fn();
|
|
34
|
+
debug = vi.fn();
|
|
35
|
+
info = vi.fn();
|
|
36
|
+
warn = vi.fn();
|
|
37
|
+
error = vi.fn();
|
|
38
|
+
},
|
|
39
|
+
MatrixClient: params.matrixClient ?? class {},
|
|
40
|
+
LogService: {
|
|
41
|
+
setLogger: vi.fn(),
|
|
42
|
+
...(params.includeVerboseLogService
|
|
43
|
+
? {
|
|
44
|
+
warn: vi.fn(),
|
|
45
|
+
info: vi.fn(),
|
|
46
|
+
debug: vi.fn(),
|
|
47
|
+
}
|
|
48
|
+
: {}),
|
|
49
|
+
},
|
|
50
|
+
SimpleFsStorageProvider: params.simpleFsStorageProvider ?? class {},
|
|
51
|
+
RustSdkCryptoStorageProvider: params.rustSdkCryptoStorageProvider ?? class {},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import {
|
|
3
|
+
createActionGate,
|
|
4
|
+
jsonResult,
|
|
5
|
+
readNumberParam,
|
|
6
|
+
readReactionParams,
|
|
7
|
+
readStringParam,
|
|
8
|
+
} from "openclaw/plugin-sdk/matrix";
|
|
9
|
+
import {
|
|
10
|
+
deleteMatrixMessage,
|
|
11
|
+
editMatrixMessage,
|
|
12
|
+
getMatrixMemberInfo,
|
|
13
|
+
getMatrixRoomInfo,
|
|
14
|
+
listMatrixPins,
|
|
15
|
+
listMatrixReactions,
|
|
16
|
+
pinMatrixMessage,
|
|
17
|
+
readMatrixMessages,
|
|
18
|
+
removeMatrixReactions,
|
|
19
|
+
sendMatrixMessage,
|
|
20
|
+
unpinMatrixMessage,
|
|
21
|
+
} from "./matrix/actions.js";
|
|
22
|
+
import { reactMatrixMessage } from "./matrix/send.js";
|
|
23
|
+
import type { CoreConfig } from "./types.js";
|
|
24
|
+
|
|
25
|
+
const messageActions = new Set(["sendMessage", "editMessage", "deleteMessage", "readMessages"]);
|
|
26
|
+
const reactionActions = new Set(["react", "reactions"]);
|
|
27
|
+
const pinActions = new Set(["pinMessage", "unpinMessage", "listPins"]);
|
|
28
|
+
|
|
29
|
+
function readRoomId(params: Record<string, unknown>, required = true): string {
|
|
30
|
+
const direct = readStringParam(params, "roomId") ?? readStringParam(params, "channelId");
|
|
31
|
+
if (direct) {
|
|
32
|
+
return direct;
|
|
33
|
+
}
|
|
34
|
+
if (!required) {
|
|
35
|
+
return readStringParam(params, "to") ?? "";
|
|
36
|
+
}
|
|
37
|
+
return readStringParam(params, "to", { required: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function handleMatrixAction(
|
|
41
|
+
params: Record<string, unknown>,
|
|
42
|
+
cfg: CoreConfig,
|
|
43
|
+
): Promise<AgentToolResult<unknown>> {
|
|
44
|
+
const action = readStringParam(params, "action", { required: true });
|
|
45
|
+
const isActionEnabled = createActionGate(cfg.channels?.badgerclaw?.actions);
|
|
46
|
+
|
|
47
|
+
if (reactionActions.has(action)) {
|
|
48
|
+
if (!isActionEnabled("reactions")) {
|
|
49
|
+
throw new Error("BadgerClaw reactions are disabled.");
|
|
50
|
+
}
|
|
51
|
+
const roomId = readRoomId(params);
|
|
52
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
53
|
+
if (action === "react") {
|
|
54
|
+
const { emoji, remove, isEmpty } = readReactionParams(params, {
|
|
55
|
+
removeErrorMessage: "Emoji is required to remove a BadgerClaw reaction.",
|
|
56
|
+
});
|
|
57
|
+
if (remove || isEmpty) {
|
|
58
|
+
const result = await removeMatrixReactions(roomId, messageId, {
|
|
59
|
+
emoji: remove ? emoji : undefined,
|
|
60
|
+
});
|
|
61
|
+
return jsonResult({ ok: true, removed: result.removed });
|
|
62
|
+
}
|
|
63
|
+
await reactMatrixMessage(roomId, messageId, emoji);
|
|
64
|
+
return jsonResult({ ok: true, added: emoji });
|
|
65
|
+
}
|
|
66
|
+
const reactions = await listMatrixReactions(roomId, messageId);
|
|
67
|
+
return jsonResult({ ok: true, reactions });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (messageActions.has(action)) {
|
|
71
|
+
if (!isActionEnabled("messages")) {
|
|
72
|
+
throw new Error("BadgerClaw messages are disabled.");
|
|
73
|
+
}
|
|
74
|
+
switch (action) {
|
|
75
|
+
case "sendMessage": {
|
|
76
|
+
const to = readStringParam(params, "to", { required: true });
|
|
77
|
+
const content = readStringParam(params, "content", {
|
|
78
|
+
required: true,
|
|
79
|
+
allowEmpty: true,
|
|
80
|
+
});
|
|
81
|
+
const mediaUrl = readStringParam(params, "mediaUrl");
|
|
82
|
+
const replyToId =
|
|
83
|
+
readStringParam(params, "replyToId") ?? readStringParam(params, "replyTo");
|
|
84
|
+
const threadId = readStringParam(params, "threadId");
|
|
85
|
+
const result = await sendMatrixMessage(to, content, {
|
|
86
|
+
mediaUrl: mediaUrl ?? undefined,
|
|
87
|
+
replyToId: replyToId ?? undefined,
|
|
88
|
+
threadId: threadId ?? undefined,
|
|
89
|
+
});
|
|
90
|
+
return jsonResult({ ok: true, result });
|
|
91
|
+
}
|
|
92
|
+
case "editMessage": {
|
|
93
|
+
const roomId = readRoomId(params);
|
|
94
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
95
|
+
const content = readStringParam(params, "content", { required: true });
|
|
96
|
+
const result = await editMatrixMessage(roomId, messageId, content);
|
|
97
|
+
return jsonResult({ ok: true, result });
|
|
98
|
+
}
|
|
99
|
+
case "deleteMessage": {
|
|
100
|
+
const roomId = readRoomId(params);
|
|
101
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
102
|
+
const reason = readStringParam(params, "reason");
|
|
103
|
+
await deleteMatrixMessage(roomId, messageId, { reason: reason ?? undefined });
|
|
104
|
+
return jsonResult({ ok: true, deleted: true });
|
|
105
|
+
}
|
|
106
|
+
case "readMessages": {
|
|
107
|
+
const roomId = readRoomId(params);
|
|
108
|
+
const limit = readNumberParam(params, "limit", { integer: true });
|
|
109
|
+
const before = readStringParam(params, "before");
|
|
110
|
+
const after = readStringParam(params, "after");
|
|
111
|
+
const result = await readMatrixMessages(roomId, {
|
|
112
|
+
limit: limit ?? undefined,
|
|
113
|
+
before: before ?? undefined,
|
|
114
|
+
after: after ?? undefined,
|
|
115
|
+
});
|
|
116
|
+
return jsonResult({ ok: true, ...result });
|
|
117
|
+
}
|
|
118
|
+
default:
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (pinActions.has(action)) {
|
|
124
|
+
if (!isActionEnabled("pins")) {
|
|
125
|
+
throw new Error("BadgerClaw pins are disabled.");
|
|
126
|
+
}
|
|
127
|
+
const roomId = readRoomId(params);
|
|
128
|
+
if (action === "pinMessage") {
|
|
129
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
130
|
+
const result = await pinMatrixMessage(roomId, messageId);
|
|
131
|
+
return jsonResult({ ok: true, pinned: result.pinned });
|
|
132
|
+
}
|
|
133
|
+
if (action === "unpinMessage") {
|
|
134
|
+
const messageId = readStringParam(params, "messageId", { required: true });
|
|
135
|
+
const result = await unpinMatrixMessage(roomId, messageId);
|
|
136
|
+
return jsonResult({ ok: true, pinned: result.pinned });
|
|
137
|
+
}
|
|
138
|
+
const result = await listMatrixPins(roomId);
|
|
139
|
+
return jsonResult({ ok: true, pinned: result.pinned, events: result.events });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (action === "memberInfo") {
|
|
143
|
+
if (!isActionEnabled("memberInfo")) {
|
|
144
|
+
throw new Error("BadgerClaw member info is disabled.");
|
|
145
|
+
}
|
|
146
|
+
const userId = readStringParam(params, "userId", { required: true });
|
|
147
|
+
const roomId = readStringParam(params, "roomId") ?? readStringParam(params, "channelId");
|
|
148
|
+
const result = await getMatrixMemberInfo(userId, {
|
|
149
|
+
roomId: roomId ?? undefined,
|
|
150
|
+
});
|
|
151
|
+
return jsonResult({ ok: true, member: result });
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (action === "channelInfo") {
|
|
155
|
+
if (!isActionEnabled("channelInfo")) {
|
|
156
|
+
throw new Error("BadgerClaw room info is disabled.");
|
|
157
|
+
}
|
|
158
|
+
const roomId = readRoomId(params);
|
|
159
|
+
const result = await getMatrixRoomInfo(roomId);
|
|
160
|
+
return jsonResult({ ok: true, room: result });
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
throw new Error(`Unsupported BadgerClaw action: ${action}`);
|
|
164
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { DmPolicy, GroupPolicy, SecretInput } from "openclaw/plugin-sdk/matrix";
|
|
2
|
+
export type { DmPolicy, GroupPolicy };
|
|
3
|
+
|
|
4
|
+
export type ReplyToMode = "off" | "first" | "all";
|
|
5
|
+
|
|
6
|
+
export type MatrixDmConfig = {
|
|
7
|
+
/** If false, ignore all incoming Matrix DMs. Default: true. */
|
|
8
|
+
enabled?: boolean;
|
|
9
|
+
/** Direct message access policy (default: pairing). */
|
|
10
|
+
policy?: DmPolicy;
|
|
11
|
+
/** Allowlist for DM senders (matrix user IDs or "*"). */
|
|
12
|
+
allowFrom?: Array<string | number>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type MatrixRoomConfig = {
|
|
16
|
+
/** If false, disable the bot in this room (alias for allow: false). */
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
/** Legacy room allow toggle; prefer enabled. */
|
|
19
|
+
allow?: boolean;
|
|
20
|
+
/** Require mentioning the bot to trigger replies. */
|
|
21
|
+
requireMention?: boolean;
|
|
22
|
+
/** Optional tool policy overrides for this room. */
|
|
23
|
+
tools?: { allow?: string[]; deny?: string[] };
|
|
24
|
+
/** If true, reply without mention requirements. */
|
|
25
|
+
autoReply?: boolean;
|
|
26
|
+
/** Optional allowlist for room senders (matrix user IDs). */
|
|
27
|
+
users?: Array<string | number>;
|
|
28
|
+
/** Optional skill filter for this room. */
|
|
29
|
+
skills?: string[];
|
|
30
|
+
/** Optional system prompt snippet for this room. */
|
|
31
|
+
systemPrompt?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type MatrixActionConfig = {
|
|
35
|
+
reactions?: boolean;
|
|
36
|
+
messages?: boolean;
|
|
37
|
+
pins?: boolean;
|
|
38
|
+
memberInfo?: boolean;
|
|
39
|
+
channelInfo?: boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Per-account Matrix config (excludes the accounts field to prevent recursion). */
|
|
43
|
+
export type MatrixAccountConfig = Omit<MatrixConfig, "accounts">;
|
|
44
|
+
|
|
45
|
+
export type MatrixConfig = {
|
|
46
|
+
/** Optional display name for this account (used in CLI/UI lists). */
|
|
47
|
+
name?: string;
|
|
48
|
+
/** If false, do not start Matrix. Default: true. */
|
|
49
|
+
enabled?: boolean;
|
|
50
|
+
/** Multi-account configuration keyed by account ID. */
|
|
51
|
+
accounts?: Record<string, MatrixAccountConfig>;
|
|
52
|
+
/** Optional default account id when multiple accounts are configured. */
|
|
53
|
+
defaultAccount?: string;
|
|
54
|
+
/** Matrix homeserver URL (https://matrix.example.org). */
|
|
55
|
+
homeserver?: string;
|
|
56
|
+
/** Matrix user id (@user:server). */
|
|
57
|
+
userId?: string;
|
|
58
|
+
/** Matrix access token. */
|
|
59
|
+
accessToken?: string;
|
|
60
|
+
/** Matrix password (used only to fetch access token). */
|
|
61
|
+
password?: SecretInput;
|
|
62
|
+
/** Optional device name when logging in via password. */
|
|
63
|
+
deviceName?: string;
|
|
64
|
+
/** Initial sync limit for startup (default: @vector-im/matrix-bot-sdk default). */
|
|
65
|
+
initialSyncLimit?: number;
|
|
66
|
+
/** Enable end-to-end encryption (E2EE). Default: false. */
|
|
67
|
+
encryption?: boolean;
|
|
68
|
+
/** If true, enforce allowlists for groups + DMs regardless of policy. */
|
|
69
|
+
allowlistOnly?: boolean;
|
|
70
|
+
/** Group message policy (default: allowlist). */
|
|
71
|
+
groupPolicy?: GroupPolicy;
|
|
72
|
+
/** Allowlist for group senders (matrix user IDs). */
|
|
73
|
+
groupAllowFrom?: Array<string | number>;
|
|
74
|
+
/** Control reply threading when reply tags are present (off|first|all). */
|
|
75
|
+
replyToMode?: ReplyToMode;
|
|
76
|
+
/** How to handle thread replies (off|inbound|always). */
|
|
77
|
+
threadReplies?: "off" | "inbound" | "always";
|
|
78
|
+
/** Outbound text chunk size (chars). Default: 4000. */
|
|
79
|
+
textChunkLimit?: number;
|
|
80
|
+
/** Chunking mode: "length" (default) splits by size; "newline" splits on every newline. */
|
|
81
|
+
chunkMode?: "length" | "newline";
|
|
82
|
+
/** Outbound response prefix override for this channel/account. */
|
|
83
|
+
responsePrefix?: string;
|
|
84
|
+
/** Max outbound media size in MB. */
|
|
85
|
+
mediaMaxMb?: number;
|
|
86
|
+
/** Auto-join invites (always|allowlist|off). Default: always. */
|
|
87
|
+
autoJoin?: "always" | "allowlist" | "off";
|
|
88
|
+
/** Allowlist for auto-join invites (room IDs, aliases). */
|
|
89
|
+
autoJoinAllowlist?: Array<string | number>;
|
|
90
|
+
/** Direct message policy + allowlist overrides. */
|
|
91
|
+
dm?: MatrixDmConfig;
|
|
92
|
+
/** Room config allowlist keyed by room ID or alias (names resolved to IDs when possible). */
|
|
93
|
+
groups?: Record<string, MatrixRoomConfig>;
|
|
94
|
+
/** Room config allowlist keyed by room ID or alias. Legacy; use groups. */
|
|
95
|
+
rooms?: Record<string, MatrixRoomConfig>;
|
|
96
|
+
/** Per-action tool gating (default: true for all). */
|
|
97
|
+
actions?: MatrixActionConfig;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export type CoreConfig = {
|
|
101
|
+
channels?: {
|
|
102
|
+
badgerclaw?: MatrixConfig;
|
|
103
|
+
defaults?: {
|
|
104
|
+
groupPolicy?: "open" | "allowlist" | "disabled";
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
commands?: {
|
|
108
|
+
useAccessGroups?: boolean;
|
|
109
|
+
};
|
|
110
|
+
session?: {
|
|
111
|
+
store?: string;
|
|
112
|
+
};
|
|
113
|
+
messages?: {
|
|
114
|
+
ackReaction?: string;
|
|
115
|
+
ackReactionScope?: "group-mentions" | "group-all" | "direct" | "all" | "off" | "none";
|
|
116
|
+
};
|
|
117
|
+
[key: string]: unknown;
|
|
118
|
+
};
|