refactor: share reaction schemas and notes
This commit is contained in:
@@ -33,8 +33,7 @@ Status: ready for DM and guild text channels via the official Discord bot gatewa
|
|||||||
- Full command list + config: [Slash commands](/tools/slash-commands)
|
- Full command list + config: [Slash commands](/tools/slash-commands)
|
||||||
11. Optional guild context history: set `discord.historyLimit` (default 20) to include the last N guild messages as context when replying to a mention. Set `0` to disable.
|
11. Optional guild context history: set `discord.historyLimit` (default 20) to include the last N guild messages as context when replying to a mention. Set `0` to disable.
|
||||||
12. Reactions: the agent can trigger reactions via the `discord` tool (gated by `discord.actions.*`).
|
12. Reactions: the agent can trigger reactions via the `discord` tool (gated by `discord.actions.*`).
|
||||||
- `emoji=""` removes the bot's reaction(s) on the message.
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
||||||
- `remove: true` removes the specific emoji reaction.
|
|
||||||
- The `discord` tool is only exposed when the current provider is Discord.
|
- The `discord` tool is only exposed when the current provider is Discord.
|
||||||
13. Native commands use isolated session keys (`discord:slash:${userId}`) rather than the shared `main` session.
|
13. Native commands use isolated session keys (`discord:slash:${userId}`) rather than the shared `main` session.
|
||||||
|
|
||||||
|
|||||||
@@ -222,5 +222,5 @@ Slack tool actions can be gated with `slack.actions.*`:
|
|||||||
## Notes
|
## Notes
|
||||||
- Mention gating is controlled via `slack.channels` (set `requireMention` to `true`); `routing.groupChat.mentionPatterns` also count as mentions.
|
- Mention gating is controlled via `slack.channels` (set `requireMention` to `true`); `routing.groupChat.mentionPatterns` also count as mentions.
|
||||||
- Reaction notifications follow `slack.reactionNotifications` (use `reactionAllowlist` with mode `allowlist`).
|
- Reaction notifications follow `slack.reactionNotifications` (use `reactionAllowlist` with mode `allowlist`).
|
||||||
- For the Slack tool, `emoji=""` removes the bot's reaction(s) on the message; `remove: true` removes a specific emoji reaction.
|
- For the Slack tool, reaction removal semantics are in [/tools/reactions](/tools/reactions).
|
||||||
- Attachments are downloaded to the media store when permitted and under the size limit.
|
- Attachments are downloaded to the media store when permitted and under the size limit.
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ Controlled by `telegram.replyToMode`:
|
|||||||
|
|
||||||
## Agent tool (reactions)
|
## Agent tool (reactions)
|
||||||
- Tool: `telegram` with `react` action (`chatId`, `messageId`, `emoji`).
|
- Tool: `telegram` with `react` action (`chatId`, `messageId`, `emoji`).
|
||||||
- `emoji=""` removes the bot's reaction(s) on the message.
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
||||||
- `remove: true` removes the reaction (Telegram only supports removing your own reaction).
|
|
||||||
- Tool gating: `telegram.actions.reactions` (default: enabled).
|
- Tool gating: `telegram.actions.reactions` (default: enabled).
|
||||||
|
|
||||||
## Delivery targets (CLI/cron)
|
## Delivery targets (CLI/cron)
|
||||||
|
|||||||
@@ -97,8 +97,7 @@ WhatsApp requires a real mobile number for verification. VoIP and virtual number
|
|||||||
## Agent tool (reactions)
|
## Agent tool (reactions)
|
||||||
- Tool: `whatsapp` with `react` action (`chatJid`, `messageId`, `emoji`, optional `remove`).
|
- Tool: `whatsapp` with `react` action (`chatJid`, `messageId`, `emoji`, optional `remove`).
|
||||||
- Optional: `participant` (group sender), `fromMe` (reacting to your own message), `accountId` (multi-account).
|
- Optional: `participant` (group sender), `fromMe` (reacting to your own message), `accountId` (multi-account).
|
||||||
- `emoji=""` removes the bot's reaction(s) on the message.
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
||||||
- `remove: true` removes the bot's reaction (same effect as empty emoji).
|
|
||||||
- Tool gating: `whatsapp.actions.reactions` (default: enabled).
|
- Tool gating: `whatsapp.actions.reactions` (default: enabled).
|
||||||
|
|
||||||
## Outbound send (text + media)
|
## Outbound send (text + media)
|
||||||
|
|||||||
@@ -201,8 +201,7 @@ Notes:
|
|||||||
- `to` accepts `channel:<id>` or `user:<id>`.
|
- `to` accepts `channel:<id>` or `user:<id>`.
|
||||||
- Polls require 2–10 answers and default to 24 hours.
|
- Polls require 2–10 answers and default to 24 hours.
|
||||||
- `reactions` returns per-emoji user lists (limited to 100 per reaction).
|
- `reactions` returns per-emoji user lists (limited to 100 per reaction).
|
||||||
- `emoji=""` on `react` removes the bot's reaction(s) on the message.
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
||||||
- `remove: true` on `react` removes just that emoji.
|
|
||||||
- `discord.actions.*` gates Discord tool actions; `roles` + `moderation` default to `false`.
|
- `discord.actions.*` gates Discord tool actions; `roles` + `moderation` default to `false`.
|
||||||
- `searchMessages` follows the Discord preview spec (limit max 25, channel/author filters accept arrays).
|
- `searchMessages` follows the Discord preview spec (limit max 25, channel/author filters accept arrays).
|
||||||
- The tool is only exposed when the current provider is Discord.
|
- The tool is only exposed when the current provider is Discord.
|
||||||
@@ -214,8 +213,7 @@ Core actions:
|
|||||||
- `react` (`chatJid`, `messageId`, `emoji`, optional `remove`, `participant`, `fromMe`, `accountId`)
|
- `react` (`chatJid`, `messageId`, `emoji`, optional `remove`, `participant`, `fromMe`, `accountId`)
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- `emoji=""` removes the bot's reaction(s) on the message.
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
||||||
- `remove: true` removes the bot's reaction (same effect as empty emoji).
|
|
||||||
- `whatsapp.actions.*` gates WhatsApp tool actions.
|
- `whatsapp.actions.*` gates WhatsApp tool actions.
|
||||||
- The tool is only exposed when the current provider is WhatsApp.
|
- The tool is only exposed when the current provider is WhatsApp.
|
||||||
|
|
||||||
@@ -226,8 +224,7 @@ Core actions:
|
|||||||
- `react` (`chatId`, `messageId`, `emoji`, optional `remove`)
|
- `react` (`chatId`, `messageId`, `emoji`, optional `remove`)
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- `emoji=""` removes the bot's reaction(s) on the message.
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
||||||
- `remove: true` removes the reaction (Telegram only supports removing your own reaction).
|
|
||||||
- `telegram.actions.*` gates Telegram tool actions.
|
- `telegram.actions.*` gates Telegram tool actions.
|
||||||
- The tool is only exposed when the current provider is Telegram.
|
- The tool is only exposed when the current provider is Telegram.
|
||||||
|
|
||||||
|
|||||||
13
docs/tools/reactions.md
Normal file
13
docs/tools/reactions.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Reaction tooling
|
||||||
|
|
||||||
|
Shared reaction semantics across providers:
|
||||||
|
|
||||||
|
- `emoji` is required for reactions.
|
||||||
|
- `emoji=""` removes the bot's reaction(s) on the message.
|
||||||
|
- `remove: true` removes the specified emoji when supported.
|
||||||
|
|
||||||
|
Provider notes:
|
||||||
|
|
||||||
|
- **Discord/Slack**: empty `emoji` removes all of the bot's reactions on the message; `remove: true` removes just that emoji.
|
||||||
|
- **Telegram**: `remove: true` removes your own reaction (Bot API limitation).
|
||||||
|
- **WhatsApp**: `remove: true` maps to empty emoji (remove bot reaction).
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import { Type } from "@sinclair/typebox";
|
import { Type } from "@sinclair/typebox";
|
||||||
|
|
||||||
|
import { createReactionSchema } from "./reaction-schema.js";
|
||||||
|
|
||||||
export const DiscordToolSchema = Type.Union([
|
export const DiscordToolSchema = Type.Union([
|
||||||
Type.Object({
|
createReactionSchema({
|
||||||
action: Type.Literal("react"),
|
ids: {
|
||||||
channelId: Type.String(),
|
channelId: Type.String(),
|
||||||
messageId: Type.String(),
|
messageId: Type.String(),
|
||||||
emoji: Type.String(),
|
},
|
||||||
remove: Type.Optional(Type.Boolean()),
|
includeRemove: true,
|
||||||
}),
|
}),
|
||||||
Type.Object({
|
Type.Object({
|
||||||
action: Type.Literal("reactions"),
|
action: Type.Literal("reactions"),
|
||||||
|
|||||||
24
src/agents/tools/reaction-schema.ts
Normal file
24
src/agents/tools/reaction-schema.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { type TSchema, Type } from "@sinclair/typebox";
|
||||||
|
|
||||||
|
type ReactionSchemaOptions = {
|
||||||
|
action?: string;
|
||||||
|
ids: Record<string, TSchema>;
|
||||||
|
emoji?: TSchema;
|
||||||
|
includeRemove?: boolean;
|
||||||
|
extras?: Record<string, TSchema>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createReactionSchema(options: ReactionSchemaOptions) {
|
||||||
|
const schema: Record<string, TSchema> = {
|
||||||
|
action: Type.Literal(options.action ?? "react"),
|
||||||
|
...options.ids,
|
||||||
|
emoji: options.emoji ?? Type.String(),
|
||||||
|
};
|
||||||
|
if (options.includeRemove) {
|
||||||
|
schema.remove = Type.Optional(Type.Boolean());
|
||||||
|
}
|
||||||
|
if (options.extras) {
|
||||||
|
Object.assign(schema, options.extras);
|
||||||
|
}
|
||||||
|
return Type.Object(schema);
|
||||||
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import { Type } from "@sinclair/typebox";
|
import { Type } from "@sinclair/typebox";
|
||||||
|
|
||||||
|
import { createReactionSchema } from "./reaction-schema.js";
|
||||||
|
|
||||||
export const SlackToolSchema = Type.Union([
|
export const SlackToolSchema = Type.Union([
|
||||||
Type.Object({
|
createReactionSchema({
|
||||||
action: Type.Literal("react"),
|
ids: {
|
||||||
channelId: Type.String(),
|
channelId: Type.String(),
|
||||||
messageId: Type.String(),
|
messageId: Type.String(),
|
||||||
emoji: Type.String(),
|
},
|
||||||
remove: Type.Optional(Type.Boolean()),
|
includeRemove: true,
|
||||||
}),
|
}),
|
||||||
Type.Object({
|
Type.Object({
|
||||||
action: Type.Literal("reactions"),
|
action: Type.Literal("reactions"),
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { Type } from "@sinclair/typebox";
|
import { Type } from "@sinclair/typebox";
|
||||||
|
|
||||||
|
import { createReactionSchema } from "./reaction-schema.js";
|
||||||
|
|
||||||
export const TelegramToolSchema = Type.Union([
|
export const TelegramToolSchema = Type.Union([
|
||||||
Type.Object({
|
createReactionSchema({
|
||||||
action: Type.Literal("react"),
|
ids: {
|
||||||
chatId: Type.Union([Type.String(), Type.Number()]),
|
chatId: Type.Union([Type.String(), Type.Number()]),
|
||||||
messageId: Type.Union([Type.String(), Type.Number()]),
|
messageId: Type.Union([Type.String(), Type.Number()]),
|
||||||
emoji: Type.String(),
|
},
|
||||||
remove: Type.Optional(Type.Boolean()),
|
includeRemove: true,
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
import { Type } from "@sinclair/typebox";
|
import { Type } from "@sinclair/typebox";
|
||||||
|
|
||||||
|
import { createReactionSchema } from "./reaction-schema.js";
|
||||||
|
|
||||||
export const WhatsAppToolSchema = Type.Union([
|
export const WhatsAppToolSchema = Type.Union([
|
||||||
Type.Object({
|
createReactionSchema({
|
||||||
action: Type.Literal("react"),
|
ids: {
|
||||||
chatJid: Type.String(),
|
chatJid: Type.String(),
|
||||||
messageId: Type.String(),
|
messageId: Type.String(),
|
||||||
emoji: Type.String(),
|
},
|
||||||
remove: Type.Optional(Type.Boolean()),
|
includeRemove: true,
|
||||||
participant: Type.Optional(Type.String()),
|
extras: {
|
||||||
accountId: Type.Optional(Type.String()),
|
participant: Type.Optional(Type.String()),
|
||||||
fromMe: Type.Optional(Type.Boolean()),
|
accountId: Type.Optional(Type.String()),
|
||||||
|
fromMe: Type.Optional(Type.Boolean()),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user