Files
zCode-CLI-X/src/bot/message-sender.js
admin cbe816a421 feat: full service exposure with grammy bot + claudegram patterns
- Rewrote bot/index.js using grammy (@grammyjs/auto-retry + runner)
- Added deduplication.js (adapted from claudegram)
- Added request-queue.js (per-chat sequential processing)
- Added message-sender.js (chunking + Markdown fallback)
- Wired all JS-shim services: tools, skills, agents, config, RTK
- Added function calling support to ZAIProvider.chat()
- Added dynamic command routing (tools, skills, agents, model, stats)
- Added per-agent delegation commands (/agent_coder, /agent_architect, etc.)
- Added dedup + queue patterns from claudegram's battle-tested codebase
- Updated zcode.js to pass agents to initBot()
- Updated README feature comparison table to reflect real capabilities
2026-05-05 12:41:15 +00:00

49 lines
1.2 KiB
JavaScript

// Adapted from claudegram's message-sender.ts — send with retry, chunking, fallback
import { logger } from '../utils/logger.js';
const MAX_MSG_LENGTH = 4000;
export function splitMessage(text) {
if (text.length <= MAX_MSG_LENGTH) return [text];
const chunks = [];
let remaining = text;
while (remaining.length > 0) {
chunks.push(remaining.slice(0, MAX_MSG_LENGTH));
remaining = remaining.slice(MAX_MSG_LENGTH);
}
return chunks;
}
export function escapeMarkdown(text) {
if (!text) return '';
return text
.replace(/_/g, '\\_')
.replace(/\*/g, '\\*')
.replace(/\[/g, '\\[')
.replace(/`/g, '\\`');
}
export async function sendFormatted(ctx, text) {
if (!text) return;
try {
// Try Markdown first
const chunks = splitMessage(text);
for (const chunk of chunks) {
await ctx.reply(chunk, { parse_mode: 'Markdown' });
}
} catch {
// Fallback to plain text
logger.warn('Markdown send failed, falling back to plain text');
const chunks = splitMessage(text);
for (const chunk of chunks) {
await ctx.reply(chunk, { parse_mode: undefined });
}
}
}
export async function sendLongMessage(ctx, text) {
if (!text) return;
return sendFormatted(ctx, text);
}