@friendlyrobot/discord-pi-agent 0.4.0 → 0.4.3
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/index.d.ts +1 -1
- package/dist/index.js +46 -67
- package/dist/markdown-table-transformer.d.ts +5 -10
- package/dist/message-chunker.test.d.ts +1 -0
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DiscordPiBridge, DiscordPiBridgeConfig } from "./types";
|
|
2
2
|
export { buildTimeContextPrompt, type TimeContextPromptOptions, } from "./prompt-context";
|
|
3
|
-
export { transformMarkdownTablesToCodeBlocks
|
|
3
|
+
export { transformMarkdownTablesToCodeBlocks } from "./markdown-table-transformer";
|
|
4
4
|
export { loadDiscordPiBridgeConfigFromEnv, resolveConfig } from "./config";
|
|
5
5
|
export type { AgentStatus, DiscordPiBridge, DiscordPiBridgeConfig, PromptTransform, ResolvedDiscordPiBridgeConfig, } from "./types";
|
|
6
6
|
export declare function startDiscordPiBridge(config: DiscordPiBridgeConfig): Promise<DiscordPiBridge>;
|
package/dist/index.js
CHANGED
|
@@ -14,82 +14,33 @@ import {
|
|
|
14
14
|
} from "@mariozechner/pi-coding-agent";
|
|
15
15
|
|
|
16
16
|
// src/markdown-table-transformer.ts
|
|
17
|
-
|
|
17
|
+
import { Lexer } from "marked";
|
|
18
18
|
var CODE_BLOCK_WRAPPER = "```\n{TABLE}\n```";
|
|
19
19
|
async function transformMarkdownTablesToCodeBlocks(text) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const formattedTable = formattedTables[i];
|
|
30
|
-
const wrappedTable = CODE_BLOCK_WRAPPER.replace("{TABLE}", formattedTable);
|
|
31
|
-
result = result.replace(originalTable, wrappedTable);
|
|
20
|
+
const formatted = await formatWithPrettier(text);
|
|
21
|
+
const tokens = Lexer.lex(formatted);
|
|
22
|
+
const result = [];
|
|
23
|
+
for (const token of tokens) {
|
|
24
|
+
if (token.type === "table") {
|
|
25
|
+
result.push(CODE_BLOCK_WRAPPER.replace("{TABLE}", token.raw.trimEnd()));
|
|
26
|
+
} else {
|
|
27
|
+
result.push(token.raw);
|
|
28
|
+
}
|
|
32
29
|
}
|
|
33
|
-
return result;
|
|
30
|
+
return formatWithPrettier(result.join(""));
|
|
34
31
|
}
|
|
35
|
-
function
|
|
36
|
-
const lines = table.trim().split(`
|
|
37
|
-
`);
|
|
38
|
-
return lines.map((line) => {
|
|
39
|
-
return line.split("|").filter((cell) => cell.trim() !== "").map((cell) => cell.trim());
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
async function formatTableWithPrettier(table) {
|
|
32
|
+
async function formatWithPrettier(text) {
|
|
43
33
|
const prettier = await import("prettier");
|
|
44
34
|
try {
|
|
45
|
-
const formatted = await prettier.format(
|
|
35
|
+
const formatted = await prettier.format(text, {
|
|
46
36
|
parser: "markdown",
|
|
47
37
|
printWidth: 80
|
|
48
38
|
});
|
|
49
39
|
return formatted.trim();
|
|
50
|
-
} catch {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
function formatTableManually(table) {
|
|
55
|
-
const rows = parseMarkdownTable(table);
|
|
56
|
-
if (rows.length === 0) {
|
|
57
|
-
return table;
|
|
58
|
-
}
|
|
59
|
-
const columnCount = Math.max(...rows.map((row) => row.length));
|
|
60
|
-
const columnWidths = Array(columnCount).fill(0);
|
|
61
|
-
for (const row of rows) {
|
|
62
|
-
for (let i = 0;i < row.length; i++) {
|
|
63
|
-
columnWidths[i] = Math.max(columnWidths[i], row[i].length);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const formattedRows = rows.map((row, rowIndex) => {
|
|
67
|
-
const paddedCells = row.map((cell, colIndex) => {
|
|
68
|
-
const width = columnWidths[colIndex];
|
|
69
|
-
return padCell(cell, width);
|
|
70
|
-
});
|
|
71
|
-
return "| " + paddedCells.join(" | ") + " |";
|
|
72
|
-
});
|
|
73
|
-
if (formattedRows.length > 1) {
|
|
74
|
-
const separatorCells = columnWidths.map((width) => {
|
|
75
|
-
return "-".repeat(width);
|
|
76
|
-
});
|
|
77
|
-
const separator = "| " + separatorCells.join(" | ") + " |";
|
|
78
|
-
formattedRows.splice(1, 0, separator);
|
|
79
|
-
}
|
|
80
|
-
return formattedRows.join(`
|
|
81
|
-
`);
|
|
82
|
-
}
|
|
83
|
-
function padCell(value, width) {
|
|
84
|
-
if (value.length >= width) {
|
|
85
|
-
return value;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error("[markdown-table-transformer] Prettier formatting failed:", error);
|
|
42
|
+
return text;
|
|
86
43
|
}
|
|
87
|
-
return value + " ".repeat(width - value.length);
|
|
88
|
-
}
|
|
89
|
-
function transformMarkdownTablesSync(text) {
|
|
90
|
-
return text.replace(TABLE_BLOCK_REGEX, (tableMatch) => {
|
|
91
|
-
return CODE_BLOCK_WRAPPER.replace("{TABLE}", tableMatch.trim());
|
|
92
|
-
});
|
|
93
44
|
}
|
|
94
45
|
|
|
95
46
|
// src/reply-buffer.ts
|
|
@@ -569,13 +520,16 @@ async function handleCommand(input, agentService, promptQueue) {
|
|
|
569
520
|
}
|
|
570
521
|
|
|
571
522
|
// src/message-chunker.ts
|
|
523
|
+
import { Lexer as Lexer2 } from "marked";
|
|
572
524
|
var DISCORD_MESSAGE_LIMIT = 2000;
|
|
573
525
|
var SAFE_MESSAGE_LIMIT = 1900;
|
|
574
526
|
function chunkMessage(text) {
|
|
575
527
|
if (text.length <= SAFE_MESSAGE_LIMIT) {
|
|
576
528
|
return [text];
|
|
577
529
|
}
|
|
530
|
+
const codeBlockRanges = getCodeBlockRanges(text);
|
|
578
531
|
const chunks = [];
|
|
532
|
+
let offset = 0;
|
|
579
533
|
let remaining = text;
|
|
580
534
|
while (remaining.length > SAFE_MESSAGE_LIMIT) {
|
|
581
535
|
const candidate = remaining.slice(0, SAFE_MESSAGE_LIMIT);
|
|
@@ -583,15 +537,41 @@ function chunkMessage(text) {
|
|
|
583
537
|
|
|
584
538
|
`), candidate.lastIndexOf(`
|
|
585
539
|
`), candidate.lastIndexOf(" "));
|
|
586
|
-
const
|
|
540
|
+
const relBoundary = splitIndex > 0 ? splitIndex : SAFE_MESSAGE_LIMIT;
|
|
541
|
+
const absBoundary = adjustBoundaryForCodeBlock(offset + relBoundary, codeBlockRanges);
|
|
542
|
+
const boundary = absBoundary - offset;
|
|
587
543
|
chunks.push(remaining.slice(0, boundary).trim());
|
|
588
544
|
remaining = remaining.slice(boundary).trim();
|
|
545
|
+
offset = absBoundary;
|
|
589
546
|
}
|
|
590
547
|
if (remaining.length > 0) {
|
|
591
548
|
chunks.push(remaining);
|
|
592
549
|
}
|
|
593
550
|
return chunks.filter((chunk) => chunk.length > 0).map((chunk) => chunk.slice(0, DISCORD_MESSAGE_LIMIT));
|
|
594
551
|
}
|
|
552
|
+
function getCodeBlockRanges(text) {
|
|
553
|
+
const tokens = Lexer2.lex(text);
|
|
554
|
+
const ranges = [];
|
|
555
|
+
let pos = 0;
|
|
556
|
+
for (const token of tokens) {
|
|
557
|
+
if (token.type === "code") {
|
|
558
|
+
ranges.push({ start: pos, end: pos + token.raw.length });
|
|
559
|
+
}
|
|
560
|
+
pos += token.raw.length;
|
|
561
|
+
}
|
|
562
|
+
return ranges;
|
|
563
|
+
}
|
|
564
|
+
function adjustBoundaryForCodeBlock(absBoundary, codeBlockRanges) {
|
|
565
|
+
for (const range of codeBlockRanges) {
|
|
566
|
+
if (absBoundary > range.start && absBoundary < range.end) {
|
|
567
|
+
if (range.end <= DISCORD_MESSAGE_LIMIT) {
|
|
568
|
+
return range.end;
|
|
569
|
+
}
|
|
570
|
+
return absBoundary;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
return absBoundary;
|
|
574
|
+
}
|
|
595
575
|
|
|
596
576
|
// src/discord-client.ts
|
|
597
577
|
async function startDiscordClient(config, agentService, promptQueue) {
|
|
@@ -840,7 +820,6 @@ function registerSignalHandlers(stop) {
|
|
|
840
820
|
}
|
|
841
821
|
export {
|
|
842
822
|
transformMarkdownTablesToCodeBlocks,
|
|
843
|
-
transformMarkdownTablesSync,
|
|
844
823
|
startDiscordPiBridge,
|
|
845
824
|
resolveConfig,
|
|
846
825
|
loadDiscordPiBridgeConfigFromEnv,
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Transforms markdown tables into Discord-friendly code blocks.
|
|
3
3
|
* Discord doesn't support markdown tables natively, so we:
|
|
4
|
-
* 1.
|
|
5
|
-
* 2.
|
|
6
|
-
* 3.
|
|
4
|
+
* 1. Format the entire document with Prettier (tables get formatted)
|
|
5
|
+
* 2. Use marked Lexer to identify tables
|
|
6
|
+
* 3. Wrap tables in triple backticks
|
|
7
|
+
* 4. Run Prettier once more on the entire result (tables stay formatted in code blocks)
|
|
7
8
|
*/
|
|
8
9
|
/**
|
|
9
10
|
* Transforms markdown tables in the text to Discord-friendly code blocks.
|
|
10
|
-
*
|
|
11
|
-
* Table contents are formatted with Prettier for proper column alignment.
|
|
11
|
+
* Uses marked's Lexer to properly identify tables.
|
|
12
12
|
*/
|
|
13
13
|
export declare function transformMarkdownTablesToCodeBlocks(text: string): Promise<string>;
|
|
14
|
-
/**
|
|
15
|
-
* Synchronous version that wraps tables in code blocks but skips Prettier formatting.
|
|
16
|
-
* Useful when you want quick transformation without async overhead.
|
|
17
|
-
*/
|
|
18
|
-
export declare function transformMarkdownTablesSync(text: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friendlyrobot/discord-pi-agent",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Reusable Discord gateway bridge for persistent pi agent sessions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"scripts": {
|
|
28
28
|
"test:watch": "vitest",
|
|
29
29
|
"test": "vitest run",
|
|
30
|
-
"update-deps": "bun add @mariozechner/pi-ai@latest @mariozechner/pi-coding-agent@latest discord.js@latest dotenv@latest prettier@latest; bun add -d @types/node@latest typescript@latest vitest@latest @vitest/ui@latest",
|
|
30
|
+
"update-deps": "bun add @mariozechner/pi-ai@latest @mariozechner/pi-coding-agent@latest marked@latest discord.js@latest dotenv@latest prettier@latest; bun add -d @types/node@latest typescript@latest vitest@latest @vitest/ui@latest",
|
|
31
31
|
"format": "prettier --write .",
|
|
32
32
|
"build": "rm -rf dist && bun build ./src/index.ts --outdir ./dist --target node --format esm --packages external && tsc -p tsconfig.json --emitDeclarationOnly --declaration --declarationMap false",
|
|
33
33
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"@mariozechner/pi-coding-agent": "^0.70.0",
|
|
38
38
|
"discord.js": "^14.26.3",
|
|
39
39
|
"dotenv": "^17.4.2",
|
|
40
|
+
"marked": "^18.0.2",
|
|
40
41
|
"prettier": "^3.8.3"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|