feat: configurable outbound text chunk limits
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
### Fixes
|
||||
- Chat UI: keep the chat scrolled to the latest message after switching sessions.
|
||||
- Auto-reply: stream completed reply blocks as soon as they finish (configurable default + break); skip empty tool-only blocks unless verbose.
|
||||
- Messages: make outbound text chunk limits configurable (defaults remain 4000/Discord 2000).
|
||||
- CLI onboarding: persist gateway token in config so local CLI auth works; recommend auth Off unless you need multi-machine access.
|
||||
- Control UI: accept a `?token=` URL param to auto-fill Gateway auth; onboarding now opens the dashboard with token auth when configured.
|
||||
- Agent prompt: remove hardcoded user name in system prompt example.
|
||||
|
||||
@@ -282,7 +282,17 @@ Controls inbound/outbound prefixes and timestamps.
|
||||
messages: {
|
||||
messagePrefix: "[clawdis]",
|
||||
responsePrefix: "🦞",
|
||||
timestampPrefix: "Europe/London"
|
||||
timestampPrefix: "Europe/London",
|
||||
// outbound chunk size (chars); defaults vary by surface (e.g. 4000, Discord 2000)
|
||||
textChunkLimit: 4000,
|
||||
// optional per-surface overrides
|
||||
textChunkLimitBySurface: {
|
||||
whatsapp: 4000,
|
||||
telegram: 4000,
|
||||
signal: 4000,
|
||||
imessage: 4000,
|
||||
discord: 2000
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { chunkText } from "./chunk.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "./chunk.js";
|
||||
|
||||
describe("chunkText", () => {
|
||||
it("keeps multi-line text in one chunk when under limit", () => {
|
||||
@@ -45,3 +45,30 @@ describe("chunkText", () => {
|
||||
expect(chunks).toEqual(["Supercalif", "ragilistic", "expialidoc", "ious"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveTextChunkLimit", () => {
|
||||
it("uses per-surface defaults", () => {
|
||||
expect(resolveTextChunkLimit(undefined, "whatsapp")).toBe(4000);
|
||||
expect(resolveTextChunkLimit(undefined, "telegram")).toBe(4000);
|
||||
expect(resolveTextChunkLimit(undefined, "signal")).toBe(4000);
|
||||
expect(resolveTextChunkLimit(undefined, "imessage")).toBe(4000);
|
||||
expect(resolveTextChunkLimit(undefined, "discord")).toBe(2000);
|
||||
});
|
||||
|
||||
it("supports a global override", () => {
|
||||
const cfg = { messages: { textChunkLimit: 1234 } };
|
||||
expect(resolveTextChunkLimit(cfg, "whatsapp")).toBe(1234);
|
||||
expect(resolveTextChunkLimit(cfg, "discord")).toBe(1234);
|
||||
});
|
||||
|
||||
it("prefers per-surface overrides over global", () => {
|
||||
const cfg = {
|
||||
messages: {
|
||||
textChunkLimit: 1234,
|
||||
textChunkLimitBySurface: { discord: 111 },
|
||||
},
|
||||
};
|
||||
expect(resolveTextChunkLimit(cfg, "discord")).toBe(111);
|
||||
expect(resolveTextChunkLimit(cfg, "telegram")).toBe(1234);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,43 @@
|
||||
// unintentionally breaking on newlines. Using [\s\S] keeps newlines inside
|
||||
// the chunk so messages are only split when they truly exceed the limit.
|
||||
|
||||
import type { ClawdisConfig } from "../config/config.js";
|
||||
|
||||
export type TextChunkSurface =
|
||||
| "whatsapp"
|
||||
| "telegram"
|
||||
| "discord"
|
||||
| "signal"
|
||||
| "imessage"
|
||||
| "webchat";
|
||||
|
||||
const DEFAULT_CHUNK_LIMIT_BY_SURFACE: Record<TextChunkSurface, number> = {
|
||||
whatsapp: 4000,
|
||||
telegram: 4000,
|
||||
discord: 2000,
|
||||
signal: 4000,
|
||||
imessage: 4000,
|
||||
webchat: 4000,
|
||||
};
|
||||
|
||||
export function resolveTextChunkLimit(
|
||||
cfg: Pick<ClawdisConfig, "messages"> | undefined,
|
||||
surface?: TextChunkSurface,
|
||||
): number {
|
||||
const surfaceOverride = surface
|
||||
? cfg?.messages?.textChunkLimitBySurface?.[surface]
|
||||
: undefined;
|
||||
if (typeof surfaceOverride === "number" && surfaceOverride > 0) {
|
||||
return surfaceOverride;
|
||||
}
|
||||
const globalOverride = cfg?.messages?.textChunkLimit;
|
||||
if (typeof globalOverride === "number" && globalOverride > 0) {
|
||||
return globalOverride;
|
||||
}
|
||||
if (surface) return DEFAULT_CHUNK_LIMIT_BY_SURFACE[surface];
|
||||
return 4000;
|
||||
}
|
||||
|
||||
export function chunkText(text: string, limit: number): string[] {
|
||||
if (!text) return [];
|
||||
if (limit <= 0) return [text];
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
DEFAULT_AGENT_WORKSPACE_DIR,
|
||||
ensureAgentWorkspace,
|
||||
} from "../agents/workspace.js";
|
||||
import { chunkText } from "../auto-reply/chunk.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "../auto-reply/chunk.js";
|
||||
import type { MsgContext } from "../auto-reply/templating.js";
|
||||
import {
|
||||
normalizeThinkLevel,
|
||||
@@ -524,6 +524,15 @@ export async function agentCommand(
|
||||
return;
|
||||
}
|
||||
|
||||
const deliveryTextLimit =
|
||||
deliveryProvider === "whatsapp" ||
|
||||
deliveryProvider === "telegram" ||
|
||||
deliveryProvider === "discord" ||
|
||||
deliveryProvider === "signal" ||
|
||||
deliveryProvider === "imessage"
|
||||
? resolveTextChunkLimit(cfg, deliveryProvider)
|
||||
: resolveTextChunkLimit(cfg, "whatsapp");
|
||||
|
||||
for (const payload of payloads) {
|
||||
const mediaList =
|
||||
payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
||||
@@ -564,7 +573,7 @@ export async function agentCommand(
|
||||
if (deliveryProvider === "telegram" && telegramTarget) {
|
||||
try {
|
||||
if (media.length === 0) {
|
||||
for (const chunk of chunkText(text, 4000)) {
|
||||
for (const chunk of chunkText(text, deliveryTextLimit)) {
|
||||
await deps.sendMessageTelegram(telegramTarget, chunk, {
|
||||
verbose: false,
|
||||
token: telegramToken || undefined,
|
||||
@@ -645,7 +654,7 @@ export async function agentCommand(
|
||||
if (deliveryProvider === "imessage" && imessageTarget) {
|
||||
try {
|
||||
if (media.length === 0) {
|
||||
for (const chunk of chunkText(text, 4000)) {
|
||||
for (const chunk of chunkText(text, deliveryTextLimit)) {
|
||||
await deps.sendMessageIMessage(imessageTarget, chunk, {
|
||||
maxBytes: cfg.imessage?.mediaMaxMb
|
||||
? cfg.imessage.mediaMaxMb * 1024 * 1024
|
||||
|
||||
@@ -314,6 +314,15 @@ export type MessagesConfig = {
|
||||
messagePrefix?: string; // Prefix added to all inbound messages (default: "[clawdis]" if no allowFrom, else "")
|
||||
responsePrefix?: string; // Prefix auto-added to all outbound replies (e.g., "🦞")
|
||||
timestampPrefix?: boolean | string; // true/false or IANA timezone string (default: true with UTC)
|
||||
/** Outbound text chunk size (chars). Default varies by provider (e.g. 4000, Discord 2000). */
|
||||
textChunkLimit?: number;
|
||||
/** Optional per-surface chunk overrides. */
|
||||
textChunkLimitBySurface?: Partial<
|
||||
Record<
|
||||
"whatsapp" | "telegram" | "discord" | "signal" | "imessage" | "webchat",
|
||||
number
|
||||
>
|
||||
>;
|
||||
};
|
||||
|
||||
export type BridgeBindMode = "auto" | "lan" | "tailnet" | "loopback";
|
||||
@@ -708,6 +717,17 @@ const MessagesSchema = z
|
||||
messagePrefix: z.string().optional(),
|
||||
responsePrefix: z.string().optional(),
|
||||
timestampPrefix: z.union([z.boolean(), z.string()]).optional(),
|
||||
textChunkLimit: z.number().int().positive().optional(),
|
||||
textChunkLimitBySurface: z
|
||||
.object({
|
||||
whatsapp: z.number().int().positive().optional(),
|
||||
telegram: z.number().int().positive().optional(),
|
||||
discord: z.number().int().positive().optional(),
|
||||
signal: z.number().int().positive().optional(),
|
||||
imessage: z.number().int().positive().optional(),
|
||||
webchat: z.number().int().positive().optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.optional();
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
DEFAULT_AGENT_WORKSPACE_DIR,
|
||||
ensureAgentWorkspace,
|
||||
} from "../agents/workspace.js";
|
||||
import { chunkText } from "../auto-reply/chunk.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "../auto-reply/chunk.js";
|
||||
import { normalizeThinkLevel } from "../auto-reply/thinking.js";
|
||||
import type { CliDeps } from "../cli/deps.js";
|
||||
import type { ClawdisConfig } from "../config/config.js";
|
||||
@@ -357,12 +357,13 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
};
|
||||
}
|
||||
const chatId = resolvedDelivery.to;
|
||||
const textLimit = resolveTextChunkLimit(params.cfg, "telegram");
|
||||
try {
|
||||
for (const payload of payloads) {
|
||||
const mediaList =
|
||||
payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
||||
if (mediaList.length === 0) {
|
||||
for (const chunk of chunkText(payload.text ?? "", 4000)) {
|
||||
for (const chunk of chunkText(payload.text ?? "", textLimit)) {
|
||||
await params.deps.sendMessageTelegram(chatId, chunk, {
|
||||
verbose: false,
|
||||
token: telegramToken || undefined,
|
||||
@@ -444,12 +445,13 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
};
|
||||
}
|
||||
const to = resolvedDelivery.to;
|
||||
const textLimit = resolveTextChunkLimit(params.cfg, "signal");
|
||||
try {
|
||||
for (const payload of payloads) {
|
||||
const mediaList =
|
||||
payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
||||
if (mediaList.length === 0) {
|
||||
for (const chunk of chunkText(payload.text ?? "", 4000)) {
|
||||
for (const chunk of chunkText(payload.text ?? "", textLimit)) {
|
||||
await params.deps.sendMessageSignal(to, chunk);
|
||||
}
|
||||
} else {
|
||||
@@ -482,12 +484,13 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
};
|
||||
}
|
||||
const to = resolvedDelivery.to;
|
||||
const textLimit = resolveTextChunkLimit(params.cfg, "imessage");
|
||||
try {
|
||||
for (const payload of payloads) {
|
||||
const mediaList =
|
||||
payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
||||
if (mediaList.length === 0) {
|
||||
for (const chunk of chunkText(payload.text ?? "", 4000)) {
|
||||
for (const chunk of chunkText(payload.text ?? "", textLimit)) {
|
||||
await params.deps.sendMessageIMessage(to, chunk);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { chunkText } from "../auto-reply/chunk.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "../auto-reply/chunk.js";
|
||||
import { formatAgentEnvelope } from "../auto-reply/envelope.js";
|
||||
import { getReplyFromConfig } from "../auto-reply/reply.js";
|
||||
import type { ReplyPayload } from "../auto-reply/types.js";
|
||||
@@ -111,15 +111,16 @@ async function deliverReplies(params: {
|
||||
client: Awaited<ReturnType<typeof createIMessageRpcClient>>;
|
||||
runtime: RuntimeEnv;
|
||||
maxBytes: number;
|
||||
textLimit: number;
|
||||
}) {
|
||||
const { replies, target, client, runtime, maxBytes } = params;
|
||||
const { replies, target, client, runtime, maxBytes, textLimit } = params;
|
||||
for (const payload of replies) {
|
||||
const mediaList =
|
||||
payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
||||
const text = payload.text ?? "";
|
||||
if (!text && mediaList.length === 0) continue;
|
||||
if (mediaList.length === 0) {
|
||||
for (const chunk of chunkText(text, 4000)) {
|
||||
for (const chunk of chunkText(text, textLimit)) {
|
||||
await sendMessageIMessage(target, chunk, { maxBytes, client });
|
||||
}
|
||||
} else {
|
||||
@@ -143,6 +144,7 @@ export async function monitorIMessageProvider(
|
||||
): Promise<void> {
|
||||
const runtime = resolveRuntime(opts);
|
||||
const cfg = loadConfig();
|
||||
const textLimit = resolveTextChunkLimit(cfg, "imessage");
|
||||
const allowFrom = resolveAllowFrom(opts);
|
||||
const mentionRegexes = resolveMentionRegexes(cfg);
|
||||
const includeAttachments =
|
||||
@@ -274,6 +276,7 @@ export async function monitorIMessageProvider(
|
||||
client,
|
||||
runtime,
|
||||
maxBytes: mediaMaxBytes,
|
||||
textLimit,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -302,6 +305,7 @@ export async function monitorIMessageProvider(
|
||||
client,
|
||||
runtime,
|
||||
maxBytes: mediaMaxBytes,
|
||||
textLimit,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { chunkText } from "../auto-reply/chunk.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "../auto-reply/chunk.js";
|
||||
import {
|
||||
HEARTBEAT_PROMPT,
|
||||
stripHeartbeatToken,
|
||||
@@ -292,6 +292,7 @@ async function deliverHeartbeatReply(params: {
|
||||
to: string;
|
||||
text: string;
|
||||
mediaUrls: string[];
|
||||
textLimit: number;
|
||||
deps: Required<
|
||||
Pick<
|
||||
HeartbeatDeps,
|
||||
@@ -303,10 +304,10 @@ async function deliverHeartbeatReply(params: {
|
||||
>
|
||||
>;
|
||||
}) {
|
||||
const { channel, to, text, mediaUrls, deps } = params;
|
||||
const { channel, to, text, mediaUrls, deps, textLimit } = params;
|
||||
if (channel === "whatsapp") {
|
||||
if (mediaUrls.length === 0) {
|
||||
for (const chunk of chunkText(text, 4000)) {
|
||||
for (const chunk of chunkText(text, textLimit)) {
|
||||
await deps.sendWhatsApp(to, chunk, { verbose: false });
|
||||
}
|
||||
return;
|
||||
@@ -322,7 +323,7 @@ async function deliverHeartbeatReply(params: {
|
||||
|
||||
if (channel === "signal") {
|
||||
if (mediaUrls.length === 0) {
|
||||
for (const chunk of chunkText(text, 4000)) {
|
||||
for (const chunk of chunkText(text, textLimit)) {
|
||||
await deps.sendSignal(to, chunk);
|
||||
}
|
||||
return;
|
||||
@@ -338,7 +339,7 @@ async function deliverHeartbeatReply(params: {
|
||||
|
||||
if (channel === "imessage") {
|
||||
if (mediaUrls.length === 0) {
|
||||
for (const chunk of chunkText(text, 4000)) {
|
||||
for (const chunk of chunkText(text, textLimit)) {
|
||||
await deps.sendIMessage(to, chunk);
|
||||
}
|
||||
return;
|
||||
@@ -354,7 +355,7 @@ async function deliverHeartbeatReply(params: {
|
||||
|
||||
if (channel === "telegram") {
|
||||
if (mediaUrls.length === 0) {
|
||||
for (const chunk of chunkText(text, 4000)) {
|
||||
for (const chunk of chunkText(text, textLimit)) {
|
||||
await deps.sendTelegram(to, chunk, { verbose: false });
|
||||
}
|
||||
return;
|
||||
@@ -500,11 +501,13 @@ export async function runHeartbeatOnce(opts: {
|
||||
sendSignal: opts.deps?.sendSignal ?? sendMessageSignal,
|
||||
sendIMessage: opts.deps?.sendIMessage ?? sendMessageIMessage,
|
||||
};
|
||||
const textLimit = resolveTextChunkLimit(cfg, delivery.channel);
|
||||
await deliverHeartbeatReply({
|
||||
channel: delivery.channel,
|
||||
to: delivery.to,
|
||||
text: normalized.text,
|
||||
mediaUrls,
|
||||
textLimit,
|
||||
deps,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { chunkText } from "../auto-reply/chunk.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "../auto-reply/chunk.js";
|
||||
import { formatAgentEnvelope } from "../auto-reply/envelope.js";
|
||||
import { getReplyFromConfig } from "../auto-reply/reply.js";
|
||||
import type { ReplyPayload } from "../auto-reply/types.js";
|
||||
@@ -178,15 +178,17 @@ async function deliverReplies(params: {
|
||||
account?: string;
|
||||
runtime: RuntimeEnv;
|
||||
maxBytes: number;
|
||||
textLimit: number;
|
||||
}) {
|
||||
const { replies, target, baseUrl, account, runtime, maxBytes } = params;
|
||||
const { replies, target, baseUrl, account, runtime, maxBytes, textLimit } =
|
||||
params;
|
||||
for (const payload of replies) {
|
||||
const mediaList =
|
||||
payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
||||
const text = payload.text ?? "";
|
||||
if (!text && mediaList.length === 0) continue;
|
||||
if (mediaList.length === 0) {
|
||||
for (const chunk of chunkText(text, 4000)) {
|
||||
for (const chunk of chunkText(text, textLimit)) {
|
||||
await sendMessageSignal(target, chunk, {
|
||||
baseUrl,
|
||||
account,
|
||||
@@ -215,6 +217,7 @@ export async function monitorSignalProvider(
|
||||
): Promise<void> {
|
||||
const runtime = resolveRuntime(opts);
|
||||
const cfg = loadConfig();
|
||||
const textLimit = resolveTextChunkLimit(cfg, "signal");
|
||||
const baseUrl = resolveBaseUrl(opts);
|
||||
const account = resolveAccount(opts);
|
||||
const allowFrom = resolveAllowFrom(opts);
|
||||
@@ -391,6 +394,7 @@ export async function monitorSignalProvider(
|
||||
account,
|
||||
runtime,
|
||||
maxBytes: mediaMaxBytes,
|
||||
textLimit,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -420,6 +424,7 @@ export async function monitorSignalProvider(
|
||||
account,
|
||||
runtime,
|
||||
maxBytes: mediaMaxBytes,
|
||||
textLimit,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { apiThrottler } from "@grammyjs/transformer-throttler";
|
||||
import type { ApiClientOptions, Message } from "grammy";
|
||||
import { Bot, InputFile, webhookCallback } from "grammy";
|
||||
|
||||
import { chunkText } from "../auto-reply/chunk.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "../auto-reply/chunk.js";
|
||||
import { formatAgentEnvelope } from "../auto-reply/envelope.js";
|
||||
import { getReplyFromConfig } from "../auto-reply/reply.js";
|
||||
import type { ReplyPayload } from "../auto-reply/types.js";
|
||||
@@ -60,6 +60,7 @@ export function createTelegramBot(opts: TelegramBotOptions) {
|
||||
bot.api.config.use(apiThrottler());
|
||||
|
||||
const cfg = loadConfig();
|
||||
const textLimit = resolveTextChunkLimit(cfg, "telegram");
|
||||
const allowFrom = opts.allowFrom ?? cfg.telegram?.allowFrom;
|
||||
const replyToMode = opts.replyToMode ?? cfg.telegram?.replyToMode ?? "off";
|
||||
const mediaMaxBytes =
|
||||
@@ -245,6 +246,7 @@ export function createTelegramBot(opts: TelegramBotOptions) {
|
||||
runtime,
|
||||
bot,
|
||||
replyToMode,
|
||||
textLimit,
|
||||
});
|
||||
} catch (err) {
|
||||
runtime.error?.(danger(`handler failed: ${String(err)}`));
|
||||
@@ -268,8 +270,9 @@ async function deliverReplies(params: {
|
||||
runtime: RuntimeEnv;
|
||||
bot: Bot;
|
||||
replyToMode: ReplyToMode;
|
||||
textLimit: number;
|
||||
}) {
|
||||
const { replies, chatId, runtime, bot, replyToMode } = params;
|
||||
const { replies, chatId, runtime, bot, replyToMode, textLimit } = params;
|
||||
let hasReplied = false;
|
||||
for (const reply of replies) {
|
||||
if (!reply?.text && !reply?.mediaUrl && !(reply?.mediaUrls?.length ?? 0)) {
|
||||
@@ -286,7 +289,7 @@ async function deliverReplies(params: {
|
||||
? [reply.mediaUrl]
|
||||
: [];
|
||||
if (mediaList.length === 0) {
|
||||
for (const chunk of chunkText(reply.text || "", 4000)) {
|
||||
for (const chunk of chunkText(reply.text || "", textLimit)) {
|
||||
await sendTelegramText(bot, chatId, chunk, runtime, {
|
||||
replyToMessageId:
|
||||
replyToId && (replyToMode === "all" || !hasReplied)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { chunkText } from "../auto-reply/chunk.js";
|
||||
import { chunkText, resolveTextChunkLimit } from "../auto-reply/chunk.js";
|
||||
import { formatAgentEnvelope } from "../auto-reply/envelope.js";
|
||||
import {
|
||||
normalizeGroupActivation,
|
||||
@@ -41,7 +41,6 @@ import {
|
||||
} from "./reconnect.js";
|
||||
import { formatError, getWebAuthAgeMs, readWebSelfId } from "./session.js";
|
||||
|
||||
const WEB_TEXT_LIMIT = 4000;
|
||||
const DEFAULT_GROUP_HISTORY_LIMIT = 50;
|
||||
const whatsappLog = createSubsystemLogger("gateway/providers/whatsapp");
|
||||
const whatsappInboundLog = whatsappLog.child("inbound");
|
||||
@@ -502,6 +501,7 @@ async function deliverWebReply(params: {
|
||||
replyResult: ReplyPayload;
|
||||
msg: WebInboundMsg;
|
||||
maxMediaBytes: number;
|
||||
textLimit: number;
|
||||
replyLogger: ReturnType<typeof getChildLogger>;
|
||||
connectionId?: string;
|
||||
skipLog?: boolean;
|
||||
@@ -510,12 +510,13 @@ async function deliverWebReply(params: {
|
||||
replyResult,
|
||||
msg,
|
||||
maxMediaBytes,
|
||||
textLimit,
|
||||
replyLogger,
|
||||
connectionId,
|
||||
skipLog,
|
||||
} = params;
|
||||
const replyStarted = Date.now();
|
||||
const textChunks = chunkText(replyResult.text || "", WEB_TEXT_LIMIT);
|
||||
const textChunks = chunkText(replyResult.text || "", textLimit);
|
||||
const mediaList = replyResult.mediaUrls?.length
|
||||
? replyResult.mediaUrls
|
||||
: replyResult.mediaUrl
|
||||
@@ -1050,6 +1051,7 @@ export async function monitorWebProvider(
|
||||
}
|
||||
|
||||
const responsePrefix = cfg.messages?.responsePrefix;
|
||||
const textLimit = resolveTextChunkLimit(cfg, "whatsapp");
|
||||
let didLogHeartbeatStrip = false;
|
||||
let didSendReply = false;
|
||||
let toolSendChain: Promise<void> = Promise.resolve();
|
||||
@@ -1091,6 +1093,7 @@ export async function monitorWebProvider(
|
||||
replyResult: toolPayload,
|
||||
msg,
|
||||
maxMediaBytes,
|
||||
textLimit,
|
||||
replyLogger,
|
||||
connectionId,
|
||||
skipLog: true,
|
||||
@@ -1134,6 +1137,7 @@ export async function monitorWebProvider(
|
||||
replyResult: blockPayload,
|
||||
msg,
|
||||
maxMediaBytes,
|
||||
textLimit,
|
||||
replyLogger,
|
||||
connectionId,
|
||||
skipLog: true,
|
||||
@@ -1238,6 +1242,7 @@ export async function monitorWebProvider(
|
||||
replyResult: replyPayload,
|
||||
msg,
|
||||
maxMediaBytes,
|
||||
textLimit,
|
||||
replyLogger,
|
||||
connectionId,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user