@friendlyrobot/discord-pi-agent 0.3.17 → 0.4.0
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/README.md
CHANGED
package/dist/agent-service.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare class AgentService {
|
|
|
9
9
|
constructor(config: ResolvedDiscordPiBridgeConfig);
|
|
10
10
|
initialize(): Promise<void>;
|
|
11
11
|
prompt(text: string): Promise<string>;
|
|
12
|
+
reloadResources(): Promise<string>;
|
|
12
13
|
compact(): Promise<string>;
|
|
13
14
|
resetSession(): Promise<string>;
|
|
14
15
|
getStatus(): AgentStatus;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DiscordPiBridge, DiscordPiBridgeConfig } from "./types";
|
|
2
2
|
export { buildTimeContextPrompt, type TimeContextPromptOptions, } from "./prompt-context";
|
|
3
|
+
export { transformMarkdownTablesToCodeBlocks, transformMarkdownTablesSync, } from "./markdown-table-transformer";
|
|
3
4
|
export { loadDiscordPiBridgeConfigFromEnv, resolveConfig } from "./config";
|
|
4
5
|
export type { AgentStatus, DiscordPiBridge, DiscordPiBridgeConfig, PromptTransform, ResolvedDiscordPiBridgeConfig, } from "./types";
|
|
5
6
|
export declare function startDiscordPiBridge(config: DiscordPiBridgeConfig): Promise<DiscordPiBridge>;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
+
|
|
1
4
|
// src/agent-service.ts
|
|
2
5
|
import fs from "node:fs/promises";
|
|
3
6
|
import path from "node:path";
|
|
@@ -10,6 +13,85 @@ import {
|
|
|
10
13
|
SettingsManager
|
|
11
14
|
} from "@mariozechner/pi-coding-agent";
|
|
12
15
|
|
|
16
|
+
// src/markdown-table-transformer.ts
|
|
17
|
+
var TABLE_BLOCK_REGEX = /(\|.+?(?:\|.*)+)(\n\|[-:]+(?:\|[-:]+)+\|?)(\n\|.+?(?:\|.*)+\|?)+/g;
|
|
18
|
+
var CODE_BLOCK_WRAPPER = "```\n{TABLE}\n```";
|
|
19
|
+
async function transformMarkdownTablesToCodeBlocks(text) {
|
|
20
|
+
const matches = [...text.matchAll(TABLE_BLOCK_REGEX)];
|
|
21
|
+
if (matches.length === 0) {
|
|
22
|
+
return text;
|
|
23
|
+
}
|
|
24
|
+
const formattedTables = await Promise.all(matches.map((match) => formatTableWithPrettier(match[0])));
|
|
25
|
+
let result = text;
|
|
26
|
+
for (let i = 0;i < matches.length; i++) {
|
|
27
|
+
const match = matches[i];
|
|
28
|
+
const originalTable = match[0];
|
|
29
|
+
const formattedTable = formattedTables[i];
|
|
30
|
+
const wrappedTable = CODE_BLOCK_WRAPPER.replace("{TABLE}", formattedTable);
|
|
31
|
+
result = result.replace(originalTable, wrappedTable);
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
function parseMarkdownTable(table) {
|
|
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) {
|
|
43
|
+
const prettier = await import("prettier");
|
|
44
|
+
try {
|
|
45
|
+
const formatted = await prettier.format(table, {
|
|
46
|
+
parser: "markdown",
|
|
47
|
+
printWidth: 80
|
|
48
|
+
});
|
|
49
|
+
return formatted.trim();
|
|
50
|
+
} catch {
|
|
51
|
+
return formatTableManually(table);
|
|
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;
|
|
86
|
+
}
|
|
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
|
+
}
|
|
94
|
+
|
|
13
95
|
// src/reply-buffer.ts
|
|
14
96
|
async function collectReply(session, prompt, options = {}) {
|
|
15
97
|
const logPrefix = options.logPrefix ?? "[agent]";
|
|
@@ -67,7 +149,8 @@ async function collectReply(session, prompt, options = {}) {
|
|
|
67
149
|
return errorMessage;
|
|
68
150
|
}
|
|
69
151
|
if (finalText) {
|
|
70
|
-
|
|
152
|
+
const transformed = await transformMarkdownTablesToCodeBlocks(finalText);
|
|
153
|
+
return transformed;
|
|
71
154
|
}
|
|
72
155
|
return "No response generated.";
|
|
73
156
|
}
|
|
@@ -147,6 +230,17 @@ class AgentService {
|
|
|
147
230
|
logPrefix: `[agent:${session.sessionId}]`
|
|
148
231
|
});
|
|
149
232
|
}
|
|
233
|
+
async reloadResources() {
|
|
234
|
+
await this.resourceLoader.reload();
|
|
235
|
+
const extensions = this.resourceLoader.getExtensions().extensions.map((ext) => ext.path);
|
|
236
|
+
const agentsFiles = this.resourceLoader.getAgentsFiles().agentsFiles.map((f) => f.path);
|
|
237
|
+
return [
|
|
238
|
+
"Resources reloaded.",
|
|
239
|
+
`Extensions (${extensions.length}): ${extensions.join(", ") || "(none)"}`,
|
|
240
|
+
`AGENTS.md files (${agentsFiles.length}): ${agentsFiles.join(", ") || "(none)"}`
|
|
241
|
+
].join(`
|
|
242
|
+
`);
|
|
243
|
+
}
|
|
150
244
|
async compact() {
|
|
151
245
|
const session = this.requireSession();
|
|
152
246
|
await session.compact();
|
|
@@ -391,6 +485,7 @@ async function handleCommand(input, agentService, promptQueue) {
|
|
|
391
485
|
"!thinking - show or set thinking/reasoning level",
|
|
392
486
|
"!compact - compact the persistent session",
|
|
393
487
|
"!reset-session - start a fresh persistent session",
|
|
488
|
+
"!reload - reload resources (AGENTS.md, extensions, skills, etc.)",
|
|
394
489
|
"Any other DM text goes to the persistent agent session."
|
|
395
490
|
].join(`
|
|
396
491
|
`)
|
|
@@ -451,6 +546,14 @@ async function handleCommand(input, agentService, promptQueue) {
|
|
|
451
546
|
})
|
|
452
547
|
};
|
|
453
548
|
}
|
|
549
|
+
if (trimmed === "!reload") {
|
|
550
|
+
return {
|
|
551
|
+
handled: true,
|
|
552
|
+
response: await promptQueue.enqueue(async () => {
|
|
553
|
+
return agentService.reloadResources();
|
|
554
|
+
})
|
|
555
|
+
};
|
|
556
|
+
}
|
|
454
557
|
if (trimmed === "!reset-session") {
|
|
455
558
|
return {
|
|
456
559
|
handled: true,
|
|
@@ -736,6 +839,8 @@ function registerSignalHandlers(stop) {
|
|
|
736
839
|
});
|
|
737
840
|
}
|
|
738
841
|
export {
|
|
842
|
+
transformMarkdownTablesToCodeBlocks,
|
|
843
|
+
transformMarkdownTablesSync,
|
|
739
844
|
startDiscordPiBridge,
|
|
740
845
|
resolveConfig,
|
|
741
846
|
loadDiscordPiBridgeConfigFromEnv,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transforms markdown tables into Discord-friendly code blocks.
|
|
3
|
+
* Discord doesn't support markdown tables natively, so we:
|
|
4
|
+
* 1. Detect markdown tables in the text
|
|
5
|
+
* 2. Wrap them in triple backticks
|
|
6
|
+
* 3. Use Prettier to format the table with proper column alignment
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Transforms markdown tables in the text to Discord-friendly code blocks.
|
|
10
|
+
* Tables are detected by their markdown syntax and wrapped in triple backticks.
|
|
11
|
+
* Table contents are formatted with Prettier for proper column alignment.
|
|
12
|
+
*/
|
|
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.
|
|
3
|
+
"version": "0.4.0",
|
|
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; bun add -d @types/node@latest
|
|
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",
|
|
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"
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
"@mariozechner/pi-ai": "^0.70.0",
|
|
37
37
|
"@mariozechner/pi-coding-agent": "^0.70.0",
|
|
38
38
|
"discord.js": "^14.26.3",
|
|
39
|
-
"dotenv": "^17.4.2"
|
|
39
|
+
"dotenv": "^17.4.2",
|
|
40
|
+
"prettier": "^3.8.3"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/node": "^25.6.0",
|
|
43
44
|
"@vitest/ui": "^4.1.5",
|
|
44
|
-
"prettier": "^3.8.3",
|
|
45
45
|
"typescript": "^6.0.3",
|
|
46
46
|
"vitest": "^4.1.5"
|
|
47
47
|
}
|