@friendlyrobot/discord-pi-agent 0.22.3 → 0.22.4
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/dist/discord-replies.js
CHANGED
|
@@ -5,10 +5,13 @@ const DISCORD_MESSAGE_LIMIT = 2000;
|
|
|
5
5
|
const FENCE_OVERHEAD = 8; // \`\`\`\n + \n\`\`\`
|
|
6
6
|
const MAX_CODE_FENCE_CONTENT = DISCORD_MESSAGE_LIMIT - FENCE_OVERHEAD;
|
|
7
7
|
/**
|
|
8
|
-
* Splits text by newlines into chunks that fit within maxSize.
|
|
8
|
+
* Splits plain text by newlines into chunks that fit within maxSize.
|
|
9
9
|
* Keeps lines intact unless a single line exceeds maxSize.
|
|
10
|
+
*
|
|
11
|
+
* Unlike chunkMessage (markdown-aware, token-level), this is for
|
|
12
|
+
* raw text without markdown structure (e.g. command output).
|
|
10
13
|
*/
|
|
11
|
-
function
|
|
14
|
+
function splitPlainTextIntoChunks(text, maxSize) {
|
|
12
15
|
const lines = text.split("\n");
|
|
13
16
|
const chunks = [];
|
|
14
17
|
let current = "";
|
|
@@ -126,7 +129,7 @@ export async function sendCommandReply(message, text) {
|
|
|
126
129
|
}, "command reply skipped, channel not sendable");
|
|
127
130
|
return;
|
|
128
131
|
}
|
|
129
|
-
const chunks =
|
|
132
|
+
const chunks = splitPlainTextIntoChunks(text, MAX_CODE_FENCE_CONTENT).map((c) => `\`\`\`\n${c}\n\`\`\``);
|
|
130
133
|
const [firstChunk, ...remainingChunks] = chunks;
|
|
131
134
|
if (!firstChunk) {
|
|
132
135
|
return;
|
|
@@ -3,5 +3,9 @@
|
|
|
3
3
|
* code blocks, tables, lists, and other block-level elements.
|
|
4
4
|
* Uses marked's lexer to split on token boundaries so no element
|
|
5
5
|
* gets bisected mid-structure.
|
|
6
|
+
*
|
|
7
|
+
* Code blocks larger than maxChunkSize are split into smaller
|
|
8
|
+
* sub-chunks, each wrapped in its own fences, so Discord can
|
|
9
|
+
* render each chunk as a valid code block.
|
|
6
10
|
*/
|
|
7
11
|
export declare function chunkMessage(text: string, maxChunkSize?: number): string[];
|
package/dist/message-chunker.js
CHANGED
|
@@ -6,6 +6,10 @@ const SAFE_MESSAGE_LIMIT = 1900;
|
|
|
6
6
|
* code blocks, tables, lists, and other block-level elements.
|
|
7
7
|
* Uses marked's lexer to split on token boundaries so no element
|
|
8
8
|
* gets bisected mid-structure.
|
|
9
|
+
*
|
|
10
|
+
* Code blocks larger than maxChunkSize are split into smaller
|
|
11
|
+
* sub-chunks, each wrapped in its own fences, so Discord can
|
|
12
|
+
* render each chunk as a valid code block.
|
|
9
13
|
*/
|
|
10
14
|
export function chunkMessage(text, maxChunkSize = SAFE_MESSAGE_LIMIT) {
|
|
11
15
|
if (text.length <= maxChunkSize) {
|
|
@@ -27,12 +31,55 @@ export function chunkMessage(text, maxChunkSize = SAFE_MESSAGE_LIMIT) {
|
|
|
27
31
|
};
|
|
28
32
|
for (const token of tokens) {
|
|
29
33
|
const size = token.raw.length;
|
|
34
|
+
// If adding this token would overflow AND we have existing
|
|
35
|
+
// tokens in the chunk, flush the current chunk first so the
|
|
36
|
+
// oversized token starts fresh.
|
|
30
37
|
if (currentSize + size > maxChunkSize && currentTokens.length > 0) {
|
|
31
38
|
flushChunk();
|
|
32
39
|
}
|
|
40
|
+
// If this single code block token is larger than the Discord
|
|
41
|
+
// limit, break it into smaller valid code blocks. We use
|
|
42
|
+
// DISCORD_MESSAGE_LIMIT as the threshold (not maxChunkSize)
|
|
43
|
+
// so small-chunkSize tests don't accidentally split code
|
|
44
|
+
// blocks that are fine in practice.
|
|
45
|
+
if (size > DISCORD_MESSAGE_LIMIT &&
|
|
46
|
+
token.type === "code" &&
|
|
47
|
+
currentTokens.length === 0) {
|
|
48
|
+
const subChunks = splitOversizedCodeBlock(token, maxChunkSize);
|
|
49
|
+
chunks.push(...subChunks);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
33
52
|
currentTokens.push(token);
|
|
34
53
|
currentSize += size;
|
|
35
54
|
}
|
|
36
55
|
flushChunk();
|
|
37
56
|
return chunks.map((chunk) => chunk.slice(0, DISCORD_MESSAGE_LIMIT));
|
|
38
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Split an oversized fenced code block into multiple valid
|
|
60
|
+
* code blocks, each under maxChunkSize. Each sub-chunk gets
|
|
61
|
+
* its own opening and closing fences with the same language tag.
|
|
62
|
+
*/
|
|
63
|
+
function splitOversizedCodeBlock(token, maxChunkSize) {
|
|
64
|
+
const lang = token.lang || "";
|
|
65
|
+
const fenceChar = token.raw.startsWith("```") ? "```" : "~~~";
|
|
66
|
+
const header = fenceChar + lang;
|
|
67
|
+
const footer = fenceChar;
|
|
68
|
+
// Headroom for wrapping fences plus two newlines.
|
|
69
|
+
const wrapOverhead = header.length + footer.length + 2;
|
|
70
|
+
const maxBodySize = maxChunkSize - wrapOverhead;
|
|
71
|
+
if (maxBodySize <= 0) {
|
|
72
|
+
// Fences alone eat the whole budget; just return the raw token
|
|
73
|
+
// capped at DISCORD_MESSAGE_LIMIT (handled by the final map).
|
|
74
|
+
return [token.raw];
|
|
75
|
+
}
|
|
76
|
+
const body = token.text;
|
|
77
|
+
const subChunks = [];
|
|
78
|
+
let offset = 0;
|
|
79
|
+
while (offset < body.length) {
|
|
80
|
+
const segment = body.slice(offset, offset + maxBodySize);
|
|
81
|
+
subChunks.push([header, segment, footer].join("\n"));
|
|
82
|
+
offset += maxBodySize;
|
|
83
|
+
}
|
|
84
|
+
return subChunks;
|
|
85
|
+
}
|