fix: add Telegram error suppression controls (#51914) (thanks @chinar-amrutkar)

* feat(telegram): add error policy for suppressing repetitive error messages

Introduces per-account error policy configuration that can suppress
repetitive error messages (e.g., 429 rate limit, ECONNRESET) to
prevent noisy error floods in Telegram channels.

Closes #34498

* fix(telegram): track error cooldown per message

* fix(telegram): prune expired error cooldowns

* fix: add Telegram error suppression controls (#51914) (thanks @chinar-amrutkar)

---------

Co-authored-by: chinar-amrutkar <chinar-amrutkar@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
This commit is contained in:
Chinar Amrutkar
2026-04-01 13:22:28 +01:00
committed by GitHub
parent ef286987e7
commit 74b9f22a42
7 changed files with 326 additions and 0 deletions

View File

@@ -203,6 +203,10 @@ export type TelegramAccountConfig = {
linkPreview?: boolean;
/** Send Telegram bot error replies silently (no notification sound). Default: false. */
silentErrorReplies?: boolean;
/** Controls outbound error reporting: always, once per cooldown window, or silent. */
errorPolicy?: "always" | "once" | "silent";
/** Cooldown window for `errorPolicy: "once"` in milliseconds. */
errorCooldownMs?: number;
/**
* Per-channel outbound response prefix override.
*
@@ -238,6 +242,10 @@ export type TelegramTopicConfig = {
disableAudioPreflight?: boolean;
/** Route this topic to a specific agent (overrides group-level and binding routing). */
agentId?: string;
/** Controls outbound error reporting for this topic. */
errorPolicy?: "always" | "once" | "silent";
/** Cooldown window for `errorPolicy: "once"` in milliseconds. */
errorCooldownMs?: number;
};
export type TelegramGroupConfig = {
@@ -259,6 +267,10 @@ export type TelegramGroupConfig = {
systemPrompt?: string;
/** If true, skip automatic voice-note transcription for mention detection in this group. */
disableAudioPreflight?: boolean;
/** Controls outbound error reporting for this group. */
errorPolicy?: "always" | "once" | "silent";
/** Cooldown window for `errorPolicy: "once"` in milliseconds. */
errorCooldownMs?: number;
};
/** Config for LLM-based auto-topic labeling. */
@@ -288,6 +300,10 @@ export type TelegramDirectConfig = {
allowFrom?: Array<string | number>;
/** Optional system prompt snippet for this DM. */
systemPrompt?: string;
/** Controls outbound error reporting for this DM. */
errorPolicy?: "always" | "once" | "silent";
/** Cooldown window for `errorPolicy: "once"` in milliseconds. */
errorCooldownMs?: number;
/** Auto-rename DM forum topics on first message using LLM. Default: true. */
autoTopicLabel?: AutoTopicLabelConfig;
};

View File

@@ -71,6 +71,7 @@ const SlackCapabilitiesSchema = z.union([
.strict(),
]);
const TelegramErrorPolicySchema = z.enum(["always", "once", "silent"]).optional();
export const TelegramTopicSchema = z
.object({
requireMention: z.boolean().optional(),
@@ -81,6 +82,8 @@ export const TelegramTopicSchema = z
allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
systemPrompt: z.string().optional(),
agentId: z.string().optional(),
errorPolicy: TelegramErrorPolicySchema,
errorCooldownMs: z.number().int().nonnegative().optional(),
})
.strict();
@@ -96,6 +99,8 @@ export const TelegramGroupSchema = z
allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
systemPrompt: z.string().optional(),
topics: z.record(z.string(), TelegramTopicSchema.optional()).optional(),
errorPolicy: TelegramErrorPolicySchema,
errorCooldownMs: z.number().int().nonnegative().optional(),
})
.strict();
@@ -121,6 +126,8 @@ export const TelegramDirectSchema = z
allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
systemPrompt: z.string().optional(),
topics: z.record(z.string(), TelegramTopicSchema.optional()).optional(),
errorPolicy: TelegramErrorPolicySchema,
errorCooldownMs: z.number().int().nonnegative().optional(),
requireTopic: z.boolean().optional(),
autoTopicLabel: AutoTopicLabelSchema,
})
@@ -293,6 +300,8 @@ export const TelegramAccountSchemaBase = z
silentErrorReplies: z.boolean().optional(),
responsePrefix: z.string().optional(),
ackReaction: z.string().optional(),
errorPolicy: TelegramErrorPolicySchema,
errorCooldownMs: z.number().int().nonnegative().optional(),
apiRoot: z.string().url().optional(),
autoTopicLabel: AutoTopicLabelSchema,
})