@botcord/botcord 0.1.2 → 0.1.3-beta.1
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/api.ts +3 -0
- package/index.ts +18 -26
- package/openclaw.plugin.json +1 -1
- package/package.json +12 -3
- package/runtime-api.ts +7 -0
- package/setup-entry.ts +5 -0
- package/src/channel.ts +27 -13
- package/src/commands/bind.ts +2 -2
- package/src/commands/healthcheck.ts +1 -1
- package/src/commands/register.ts +1 -2
- package/src/commands/token.ts +1 -1
- package/src/constants.ts +19 -0
- package/src/inbound.ts +1 -1
- package/src/runtime.ts +1 -1
- package/src/sanitize.ts +4 -1
- package/src/tools/account.ts +1 -0
- package/src/tools/bind.ts +1 -0
- package/src/tools/contacts.ts +1 -0
- package/src/tools/directory.ts +1 -0
- package/src/tools/messaging.ts +2 -0
- package/src/tools/notify.ts +1 -0
- package/src/tools/payment.ts +1 -0
- package/src/tools/rooms.ts +1 -0
- package/src/tools/subscription.ts +1 -0
- package/src/tools/topics.ts +1 -0
package/api.ts
ADDED
package/index.ts
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @botcord/botcord — OpenClaw plugin for BotCord A2A messaging protocol.
|
|
3
|
-
*
|
|
4
|
-
* Registers:
|
|
5
|
-
* - Channel plugin (botcord) with WebSocket + polling gateway
|
|
6
|
-
* - Agent tools: botcord_send, botcord_upload, botcord_rooms, botcord_topics, botcord_contacts, botcord_account, botcord_directory, botcord_payment, botcord_subscription, botcord_bind
|
|
7
|
-
* - Commands: /botcord_healthcheck, /botcord_token, /botcord_bind
|
|
8
|
-
* - CLI: openclaw botcord-register, openclaw botcord-import, openclaw botcord-export
|
|
9
3
|
*/
|
|
10
|
-
import
|
|
11
|
-
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
4
|
+
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
|
|
12
5
|
import { botCordPlugin } from "./src/channel.js";
|
|
13
6
|
import { setBotCordRuntime, setConfigGetter } from "./src/runtime.js";
|
|
14
7
|
import { createMessagingTool, createUploadTool } from "./src/tools/messaging.js";
|
|
@@ -33,33 +26,34 @@ import {
|
|
|
33
26
|
shouldRunBotCordLoopRiskCheck,
|
|
34
27
|
} from "./src/loop-risk.js";
|
|
35
28
|
|
|
36
|
-
|
|
29
|
+
export default defineChannelPluginEntry({
|
|
37
30
|
id: "botcord",
|
|
38
31
|
name: "BotCord",
|
|
39
32
|
description: "BotCord A2A messaging protocol — secure agent-to-agent communication with Ed25519 signing",
|
|
40
|
-
|
|
33
|
+
plugin: botCordPlugin,
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
setConfigGetter(() => api.config);
|
|
35
|
+
setRuntime(runtime) {
|
|
36
|
+
setBotCordRuntime(runtime);
|
|
37
|
+
},
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
registerFull(api) {
|
|
40
|
+
setConfigGetter(() => api.config);
|
|
49
41
|
|
|
50
|
-
//
|
|
42
|
+
// Agent tools — `as any` needed until tool execute() return types are
|
|
43
|
+
// migrated to the AgentToolResult<T> shape (P2 task).
|
|
51
44
|
api.registerTool(createMessagingTool() as any);
|
|
45
|
+
api.registerTool(createUploadTool() as any);
|
|
52
46
|
api.registerTool(createRoomsTool() as any);
|
|
53
47
|
api.registerTool(createTopicsTool() as any);
|
|
54
48
|
api.registerTool(createContactsTool() as any);
|
|
55
49
|
api.registerTool(createAccountTool() as any);
|
|
56
50
|
api.registerTool(createDirectoryTool() as any);
|
|
57
|
-
api.registerTool(createUploadTool() as any);
|
|
58
51
|
api.registerTool(createPaymentTool() as any);
|
|
59
52
|
api.registerTool(createSubscriptionTool() as any);
|
|
60
53
|
api.registerTool(createNotifyTool() as any);
|
|
61
54
|
api.registerTool(createBindTool() as any);
|
|
62
55
|
|
|
56
|
+
// Hooks
|
|
63
57
|
api.on("after_tool_call", async (event, ctx) => {
|
|
64
58
|
if (ctx.toolName !== "botcord_send") return;
|
|
65
59
|
if (!didBotCordSendSucceed(event.result, event.error)) return;
|
|
@@ -92,18 +86,16 @@ const plugin = {
|
|
|
92
86
|
clearBotCordLoopRiskSession(ctx.sessionKey);
|
|
93
87
|
});
|
|
94
88
|
|
|
95
|
-
//
|
|
96
|
-
api.registerCommand(createHealthcheckCommand()
|
|
97
|
-
api.registerCommand(createTokenCommand()
|
|
98
|
-
api.registerCommand(createBindCommand()
|
|
89
|
+
// Commands
|
|
90
|
+
api.registerCommand(createHealthcheckCommand());
|
|
91
|
+
api.registerCommand(createTokenCommand());
|
|
92
|
+
api.registerCommand(createBindCommand());
|
|
99
93
|
|
|
100
|
-
//
|
|
94
|
+
// CLI
|
|
101
95
|
const registerCli = createRegisterCli();
|
|
102
96
|
api.registerCli(registerCli.setup, { commands: registerCli.commands });
|
|
103
97
|
},
|
|
104
|
-
};
|
|
98
|
+
});
|
|
105
99
|
|
|
106
100
|
export { TopicTracker } from "./src/topic-tracker.js";
|
|
107
101
|
export type { TopicState, TopicInfo } from "./src/topic-tracker.js";
|
|
108
|
-
|
|
109
|
-
export default plugin;
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botcord/botcord",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3-beta.1",
|
|
4
4
|
"description": "OpenClaw channel plugin for BotCord A2A messaging protocol (Ed25519 signed envelopes)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.ts",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"files": [
|
|
9
9
|
"index.ts",
|
|
10
|
+
"setup-entry.ts",
|
|
11
|
+
"api.ts",
|
|
12
|
+
"runtime-api.ts",
|
|
10
13
|
"src/",
|
|
11
14
|
"!src/__tests__/",
|
|
12
15
|
"skills/",
|
|
@@ -35,11 +38,11 @@
|
|
|
35
38
|
"ws": "^8.18.0"
|
|
36
39
|
},
|
|
37
40
|
"peerDependencies": {
|
|
38
|
-
"openclaw": ">=2026.
|
|
41
|
+
"openclaw": ">=2026.3.22"
|
|
39
42
|
},
|
|
40
43
|
"devDependencies": {
|
|
41
44
|
"@types/ws": "^8.5.0",
|
|
42
|
-
"openclaw": "
|
|
45
|
+
"openclaw": "^2026.3.23",
|
|
43
46
|
"typescript": "^5.9.3",
|
|
44
47
|
"vitest": "^4.0.18"
|
|
45
48
|
},
|
|
@@ -47,6 +50,12 @@
|
|
|
47
50
|
"extensions": [
|
|
48
51
|
"./index.ts"
|
|
49
52
|
],
|
|
53
|
+
"setupEntry": "./setup-entry.ts",
|
|
54
|
+
"install": {
|
|
55
|
+
"npmSpec": "@botcord/botcord",
|
|
56
|
+
"defaultChoice": "npm",
|
|
57
|
+
"minHostVersion": ">=2026.3.22"
|
|
58
|
+
},
|
|
50
59
|
"channel": {
|
|
51
60
|
"id": "botcord",
|
|
52
61
|
"label": "BotCord",
|
package/runtime-api.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// runtime-api.ts — full runtime surface
|
|
2
|
+
export { botCordPlugin } from "./src/channel.js";
|
|
3
|
+
export { BotCordClient } from "./src/client.js";
|
|
4
|
+
export { getBotCordRuntime } from "./src/runtime.js";
|
|
5
|
+
export { TopicTracker } from "./src/topic-tracker.js";
|
|
6
|
+
export type { TopicState, TopicInfo } from "./src/topic-tracker.js";
|
|
7
|
+
export type { BotCordChannelConfig, BotCordAccountConfig, MessageAttachment } from "./src/types.js";
|
package/setup-entry.ts
ADDED
package/src/channel.ts
CHANGED
|
@@ -3,28 +3,32 @@
|
|
|
3
3
|
* outbound (send via signed envelopes), gateway (start websocket/polling),
|
|
4
4
|
* security, messaging, and status adapters.
|
|
5
5
|
*/
|
|
6
|
-
import type { ChannelPlugin, ClawdbotConfig } from "openclaw/plugin-sdk";
|
|
6
|
+
import type { ChannelPlugin, OpenClawConfig as ClawdbotConfig } from "openclaw/plugin-sdk/core";
|
|
7
7
|
import {
|
|
8
8
|
buildBaseChannelStatusSummary,
|
|
9
9
|
createDefaultChannelRuntimeState,
|
|
10
|
-
|
|
11
|
-
} from "openclaw/plugin-sdk";
|
|
10
|
+
} from "openclaw/plugin-sdk/status-helpers";
|
|
11
|
+
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
|
12
12
|
import {
|
|
13
13
|
resolveChannelConfig,
|
|
14
14
|
resolveAccounts,
|
|
15
15
|
isAccountConfigured,
|
|
16
16
|
displayPrefix,
|
|
17
17
|
} from "./config.js";
|
|
18
|
-
import { BotCordClient } from "./client.js";
|
|
19
|
-
import { getBotCordRuntime } from "./runtime.js";
|
|
20
|
-
import { startPoller, stopPoller } from "./poller.js";
|
|
21
|
-
import { startWsClient, stopWsClient } from "./ws-client.js";
|
|
22
18
|
import type {
|
|
23
19
|
BotCordAccountConfig,
|
|
24
20
|
BotCordChannelConfig,
|
|
25
21
|
MessageAttachment,
|
|
26
22
|
} from "./types.js";
|
|
27
23
|
|
|
24
|
+
// runtime.js is lightweight (no ws/network deps) — safe for static import.
|
|
25
|
+
// Heavy deps (client, poller, ws-client) are lazy-loaded so that setup-entry.ts
|
|
26
|
+
// can import botCordPlugin without pulling in ws at module level.
|
|
27
|
+
import { getBotCordRuntime } from "./runtime.js";
|
|
28
|
+
const lazyClient = () => import("./client.js").then((m) => m.BotCordClient);
|
|
29
|
+
const lazyPoller = () => import("./poller.js");
|
|
30
|
+
const lazyWsClient = () => import("./ws-client.js");
|
|
31
|
+
|
|
28
32
|
// ── Types ────────────────────────────────────────────────────────
|
|
29
33
|
|
|
30
34
|
export interface ResolvedBotCordAccount {
|
|
@@ -291,7 +295,8 @@ export const botCordPlugin: ChannelPlugin<ResolvedBotCordAccount> = {
|
|
|
291
295
|
const account = resolveBotCordAccount({ cfg: cfg as CoreConfig, accountId });
|
|
292
296
|
if (!account.configured || !account.agentId) return null;
|
|
293
297
|
try {
|
|
294
|
-
const
|
|
298
|
+
const Client = await lazyClient();
|
|
299
|
+
const client = new Client(account.config);
|
|
295
300
|
const info = await client.resolve(account.agentId);
|
|
296
301
|
return { kind: "user", id: info.agent_id, name: info.display_name || info.agent_id };
|
|
297
302
|
} catch {
|
|
@@ -302,7 +307,8 @@ export const botCordPlugin: ChannelPlugin<ResolvedBotCordAccount> = {
|
|
|
302
307
|
const account = resolveBotCordAccount({ cfg: cfg as CoreConfig, accountId });
|
|
303
308
|
if (!account.configured) return [];
|
|
304
309
|
try {
|
|
305
|
-
const
|
|
310
|
+
const Client = await lazyClient();
|
|
311
|
+
const client = new Client(account.config);
|
|
306
312
|
const contacts = await client.listContacts();
|
|
307
313
|
const q = query?.trim().toLowerCase() ?? "";
|
|
308
314
|
return contacts
|
|
@@ -326,7 +332,8 @@ export const botCordPlugin: ChannelPlugin<ResolvedBotCordAccount> = {
|
|
|
326
332
|
const account = resolveBotCordAccount({ cfg: cfg as CoreConfig, accountId });
|
|
327
333
|
if (!account.configured) return [];
|
|
328
334
|
try {
|
|
329
|
-
const
|
|
335
|
+
const Client = await lazyClient();
|
|
336
|
+
const client = new Client(account.config);
|
|
330
337
|
const rooms = await client.listMyRooms();
|
|
331
338
|
const q = query?.trim().toLowerCase() ?? "";
|
|
332
339
|
return rooms
|
|
@@ -345,7 +352,8 @@ export const botCordPlugin: ChannelPlugin<ResolvedBotCordAccount> = {
|
|
|
345
352
|
textChunkLimit: 4000,
|
|
346
353
|
sendText: async ({ cfg, to, text, accountId }) => {
|
|
347
354
|
const account = resolveBotCordAccount({ cfg: cfg as CoreConfig, accountId: accountId ?? undefined });
|
|
348
|
-
const
|
|
355
|
+
const Client = await lazyClient();
|
|
356
|
+
const client = new Client(account.config);
|
|
349
357
|
const result = await client.sendMessage(to, text);
|
|
350
358
|
return {
|
|
351
359
|
channel: "botcord",
|
|
@@ -355,7 +363,8 @@ export const botCordPlugin: ChannelPlugin<ResolvedBotCordAccount> = {
|
|
|
355
363
|
},
|
|
356
364
|
sendMedia: async ({ cfg, to, text, mediaUrl, accountId }) => {
|
|
357
365
|
const account = resolveBotCordAccount({ cfg: cfg as CoreConfig, accountId: accountId ?? undefined });
|
|
358
|
-
const
|
|
366
|
+
const Client = await lazyClient();
|
|
367
|
+
const client = new Client(account.config);
|
|
359
368
|
const attachments: MessageAttachment[] = [];
|
|
360
369
|
if (mediaUrl) {
|
|
361
370
|
const filename = mediaUrl.split("/").pop() || "attachment";
|
|
@@ -402,11 +411,13 @@ export const botCordPlugin: ChannelPlugin<ResolvedBotCordAccount> = {
|
|
|
402
411
|
const dp = displayPrefix(account.accountId, ctx.cfg);
|
|
403
412
|
ctx.log?.info(`[${dp}] starting BotCord gateway (${account.deliveryMode} mode)`);
|
|
404
413
|
|
|
405
|
-
const
|
|
414
|
+
const Client = await lazyClient();
|
|
415
|
+
const client = new Client(account.config);
|
|
406
416
|
const mode = account.deliveryMode || "websocket";
|
|
407
417
|
|
|
408
418
|
if (mode === "websocket") {
|
|
409
419
|
ctx.log?.info(`[${dp}] starting WebSocket connection to Hub`);
|
|
420
|
+
const { startWsClient } = await lazyWsClient();
|
|
410
421
|
startWsClient({
|
|
411
422
|
client,
|
|
412
423
|
accountId: account.accountId,
|
|
@@ -415,6 +426,7 @@ export const botCordPlugin: ChannelPlugin<ResolvedBotCordAccount> = {
|
|
|
415
426
|
log: ctx.log,
|
|
416
427
|
});
|
|
417
428
|
} else {
|
|
429
|
+
const { startPoller } = await lazyPoller();
|
|
418
430
|
startPoller({
|
|
419
431
|
client,
|
|
420
432
|
accountId: account.accountId,
|
|
@@ -438,6 +450,8 @@ export const botCordPlugin: ChannelPlugin<ResolvedBotCordAccount> = {
|
|
|
438
450
|
ctx.abortSignal?.addEventListener("abort", () => resolve(), { once: true });
|
|
439
451
|
});
|
|
440
452
|
|
|
453
|
+
const { stopWsClient } = await lazyWsClient();
|
|
454
|
+
const { stopPoller } = await lazyPoller();
|
|
441
455
|
stopWsClient(account.accountId);
|
|
442
456
|
stopPoller(account.accountId);
|
|
443
457
|
ctx.setStatus({ accountId: ctx.accountId, running: false, lastStopAt: Date.now() });
|
package/src/commands/bind.ts
CHANGED
|
@@ -10,8 +10,8 @@ export function createBindCommand() {
|
|
|
10
10
|
"Bind this agent to a BotCord web dashboard account using a bind ticket.",
|
|
11
11
|
acceptsArgs: true,
|
|
12
12
|
requireAuth: true,
|
|
13
|
-
handler: async (
|
|
14
|
-
const bindTicket = (args || "").trim();
|
|
13
|
+
handler: async (ctx: any) => {
|
|
14
|
+
const bindTicket = (ctx.args || "").trim();
|
|
15
15
|
if (!bindTicket) {
|
|
16
16
|
return { text: "[FAIL] Usage: /botcord_bind <bind_ticket>" };
|
|
17
17
|
}
|
|
@@ -18,7 +18,7 @@ export function createHealthcheckCommand() {
|
|
|
18
18
|
description: "Check BotCord integration health: config, Hub connectivity, token, delivery mode.",
|
|
19
19
|
acceptsArgs: false,
|
|
20
20
|
requireAuth: true,
|
|
21
|
-
handler: async () => {
|
|
21
|
+
handler: async (_ctx: any) => {
|
|
22
22
|
const lines: string[] = [];
|
|
23
23
|
let pass = 0;
|
|
24
24
|
let warn = 0;
|
package/src/commands/register.ts
CHANGED
|
@@ -25,8 +25,7 @@ import {
|
|
|
25
25
|
} from "../config.js";
|
|
26
26
|
import { normalizeAndValidateHubUrl } from "../hub-url.js";
|
|
27
27
|
import { getBotCordRuntime } from "../runtime.js";
|
|
28
|
-
|
|
29
|
-
const DEFAULT_HUB = "https://api.botcord.chat";
|
|
28
|
+
import { DEFAULT_HUB } from "../constants.js";
|
|
30
29
|
|
|
31
30
|
interface RegisterResult {
|
|
32
31
|
agentId: string;
|
package/src/commands/token.ts
CHANGED
|
@@ -15,7 +15,7 @@ export function createTokenCommand() {
|
|
|
15
15
|
description: "Fetch and display the current BotCord JWT token.",
|
|
16
16
|
acceptsArgs: false,
|
|
17
17
|
requireAuth: true,
|
|
18
|
-
handler: async () => {
|
|
18
|
+
handler: async (_ctx: any) => {
|
|
19
19
|
const cfg = getAppConfig();
|
|
20
20
|
if (!cfg) {
|
|
21
21
|
return { text: "[FAIL] No OpenClaw configuration available" };
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Release channel and environment-dependent defaults.
|
|
3
|
+
*
|
|
4
|
+
* In the stable (production) build this file ships as-is.
|
|
5
|
+
* The CI pipeline replaces the RELEASE_CHANNEL value with "beta"
|
|
6
|
+
* before publishing to the `beta` npm dist-tag, so that beta
|
|
7
|
+
* installations automatically point at the test hub.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type ReleaseChannel = "stable" | "beta";
|
|
11
|
+
|
|
12
|
+
export const RELEASE_CHANNEL: ReleaseChannel = "beta";
|
|
13
|
+
|
|
14
|
+
const HUB_URLS: Record<ReleaseChannel, string> = {
|
|
15
|
+
stable: "https://api.botcord.chat",
|
|
16
|
+
beta: "https://test.botcord.chat",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const DEFAULT_HUB = HUB_URLS[RELEASE_CHANNEL];
|
package/src/inbound.ts
CHANGED
|
@@ -227,7 +227,7 @@ async function handleA2AMessage(
|
|
|
227
227
|
// Prompt the agent to notify its owner when receiving contact requests
|
|
228
228
|
const notifyOwnerHint =
|
|
229
229
|
envelope.type === "contact_request"
|
|
230
|
-
? `\n\n[You received a contact request from ${
|
|
230
|
+
? `\n\n[You received a contact request from ${sanitizedSender}. Use the botcord_notify tool to inform your owner about this request so they can decide whether to accept or reject it. Include the sender's agent ID and any message they attached.]`
|
|
231
231
|
: "";
|
|
232
232
|
|
|
233
233
|
const sanitizedContent = sanitizeUntrustedContent(rawContent);
|
package/src/runtime.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Plugin runtime store — holds a reference to OpenClaw's PluginRuntime
|
|
3
3
|
* and a config getter for tools/hooks that need the full app config.
|
|
4
4
|
*/
|
|
5
|
-
import type { PluginRuntime } from "openclaw/plugin-sdk";
|
|
5
|
+
import type { PluginRuntime } from "openclaw/plugin-sdk/core";
|
|
6
6
|
|
|
7
7
|
let runtime: PluginRuntime | null = null;
|
|
8
8
|
let configGetter: (() => any) | null = null;
|
package/src/sanitize.ts
CHANGED
|
@@ -33,11 +33,14 @@ export function sanitizeUntrustedContent(text: string): string {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* Sanitize sender name — must not contain newlines
|
|
36
|
+
* Sanitize sender name — must not contain newlines, structural markers,
|
|
37
|
+
* or characters that could break XML attribute boundaries.
|
|
37
38
|
*/
|
|
38
39
|
export function sanitizeSenderName(name: string): string {
|
|
39
40
|
return name
|
|
40
41
|
.replace(/[\n\r]/g, " ")
|
|
41
42
|
.replace(/\[/g, "⟦").replace(/\]/g, "⟧")
|
|
43
|
+
.replace(/"/g, "'")
|
|
44
|
+
.replace(/</g, "<").replace(/>/g, ">")
|
|
42
45
|
.slice(0, 100);
|
|
43
46
|
}
|
package/src/tools/account.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { getConfig as getAppConfig } from "../runtime.js";
|
|
|
12
12
|
export function createAccountTool() {
|
|
13
13
|
return {
|
|
14
14
|
name: "botcord_account",
|
|
15
|
+
label: "Manage Account",
|
|
15
16
|
description:
|
|
16
17
|
"Manage your own BotCord agent: view identity, update profile, get/set message policy, check message delivery status.",
|
|
17
18
|
parameters: {
|
package/src/tools/bind.ts
CHANGED
package/src/tools/contacts.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { getConfig as getAppConfig } from "../runtime.js";
|
|
|
12
12
|
export function createContactsTool() {
|
|
13
13
|
return {
|
|
14
14
|
name: "botcord_contacts",
|
|
15
|
+
label: "Manage Contacts",
|
|
15
16
|
description: "Manage BotCord contacts: list/remove contacts, send/accept/reject requests, block/unblock agents.",
|
|
16
17
|
parameters: {
|
|
17
18
|
type: "object" as const,
|
package/src/tools/directory.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { getConfig as getAppConfig } from "../runtime.js";
|
|
|
12
12
|
export function createDirectoryTool() {
|
|
13
13
|
return {
|
|
14
14
|
name: "botcord_directory",
|
|
15
|
+
label: "Search Directory",
|
|
15
16
|
description: "Look up agents, discover public rooms, and query message history on BotCord.",
|
|
16
17
|
parameters: {
|
|
17
18
|
type: "object" as const,
|
package/src/tools/messaging.ts
CHANGED
|
@@ -77,6 +77,7 @@ async function uploadLocalFiles(
|
|
|
77
77
|
export function createMessagingTool() {
|
|
78
78
|
return {
|
|
79
79
|
name: "botcord_send",
|
|
80
|
+
label: "Send Message",
|
|
80
81
|
description:
|
|
81
82
|
"Send a message to another agent or room via BotCord. " +
|
|
82
83
|
"Use ag_* for direct messages, rm_* for rooms. " +
|
|
@@ -192,6 +193,7 @@ export function createMessagingTool() {
|
|
|
192
193
|
export function createUploadTool() {
|
|
193
194
|
return {
|
|
194
195
|
name: "botcord_upload",
|
|
196
|
+
label: "Upload Files",
|
|
195
197
|
description:
|
|
196
198
|
"Upload one or more local files to BotCord Hub. " +
|
|
197
199
|
"Returns file URLs that can be used later in botcord_send's file_urls parameter. " +
|
package/src/tools/notify.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { deliverNotification } from "../inbound.js";
|
|
|
11
11
|
export function createNotifyTool() {
|
|
12
12
|
return {
|
|
13
13
|
name: "botcord_notify",
|
|
14
|
+
label: "Send Notification",
|
|
14
15
|
description:
|
|
15
16
|
"Send a notification to the owner's configured channel (e.g. Telegram, Discord). " +
|
|
16
17
|
"Use this when you receive an important BotCord message that the owner should know about — " +
|
package/src/tools/payment.ts
CHANGED
|
@@ -194,6 +194,7 @@ function sanitizeLedger(data: any): any {
|
|
|
194
194
|
export function createPaymentTool(opts?: { name?: string; description?: string }) {
|
|
195
195
|
return {
|
|
196
196
|
name: opts?.name || "botcord_payment",
|
|
197
|
+
label: "Manage Payments",
|
|
197
198
|
description:
|
|
198
199
|
opts?.description ||
|
|
199
200
|
"Manage BotCord coin payments and transactions: verify recipients, check balance, view ledger, transfer coins, create topups and withdrawals, cancel withdrawals, and query transaction status.",
|
package/src/tools/rooms.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { getConfig as getAppConfig } from "../runtime.js";
|
|
|
12
12
|
export function createRoomsTool() {
|
|
13
13
|
return {
|
|
14
14
|
name: "botcord_rooms",
|
|
15
|
+
label: "Manage Rooms",
|
|
15
16
|
description:
|
|
16
17
|
"Manage BotCord rooms: create, list, join, leave, update, invite/remove members, " +
|
|
17
18
|
"set permissions, promote/transfer/dissolve, discover public rooms.",
|
|
@@ -47,6 +47,7 @@ function formatSubscriptionList(subscriptions: any[]): string {
|
|
|
47
47
|
export function createSubscriptionTool() {
|
|
48
48
|
return {
|
|
49
49
|
name: "botcord_subscription",
|
|
50
|
+
label: "Manage Subscriptions",
|
|
50
51
|
description:
|
|
51
52
|
"Create subscription products priced in BotCord coin, subscribe to products, list active subscriptions, and manage cancellation or product archiving.",
|
|
52
53
|
parameters: {
|
package/src/tools/topics.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { getConfig as getAppConfig } from "../runtime.js";
|
|
|
12
12
|
export function createTopicsTool() {
|
|
13
13
|
return {
|
|
14
14
|
name: "botcord_topics",
|
|
15
|
+
label: "Manage Topics",
|
|
15
16
|
description:
|
|
16
17
|
"Manage topics within BotCord rooms. Topics are goal-driven conversation units " +
|
|
17
18
|
"with lifecycle states: open → completed/failed/expired.",
|