pi-discord-bot 0.1.1 → 0.1.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/README.md +11 -7
- package/discord-policy.example.json +3 -4
- package/dist/agent-prompt.js +0 -10
- package/dist/agent-runner.js +10 -1
- package/dist/agent.js +12 -15
- package/dist/discord.js +11 -6
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -85,22 +85,26 @@ Unsupported in Discord:
|
|
|
85
85
|
|
|
86
86
|
### Use as a Pi package skill
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
1. **Install Pi** — follow the [Pi quick start guide](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent#quick-start) and configure your provider auth (e.g. `pi login`).
|
|
89
|
+
|
|
90
|
+
2. **Install this package** — run in your terminal:
|
|
89
91
|
|
|
90
92
|
```bash
|
|
91
93
|
pi install npm:pi-discord-bot
|
|
92
94
|
```
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
3. **Start Pi and ask your agent** — just run `pi` and ask it to help you set up the Discord bot:
|
|
95
97
|
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
+
```text
|
|
99
|
+
/skill:pi-discord-bot help me set up the bot
|
|
98
100
|
```
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
The Pi agent will walk you through creating your Discord app, configuring the token, setting up the policy file, and starting the bot. You don't need to memorize any setup steps — just ask.
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
Alternatively, from a local source checkout:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pi install /absolute/path/to/pi-discord-bot
|
|
104
108
|
```
|
|
105
109
|
|
|
106
110
|
See also:
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"allowDMs": true,
|
|
3
|
-
"guildIds": [
|
|
4
|
-
"channelIds": [
|
|
3
|
+
"guildIds": [],
|
|
4
|
+
"channelIds": [],
|
|
5
5
|
"mentionMode": "mention-only",
|
|
6
6
|
"slashCommands": {
|
|
7
|
-
"enabled": true
|
|
8
|
-
"guildId": "123456789012345678"
|
|
7
|
+
"enabled": true
|
|
9
8
|
}
|
|
10
9
|
}
|
package/dist/agent-prompt.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { loadSkillsFromDir } from "@mariozechner/pi-coding-agent";
|
|
4
3
|
export function getMemory(conversationDir) {
|
|
5
4
|
const parts = [];
|
|
6
5
|
for (const path of [join(conversationDir, "..", "MEMORY.md"), join(conversationDir, "MEMORY.md")]) {
|
|
@@ -12,15 +11,6 @@ export function getMemory(conversationDir) {
|
|
|
12
11
|
}
|
|
13
12
|
return parts.join("\n\n") || "(no memory yet)";
|
|
14
13
|
}
|
|
15
|
-
export function loadDiscordSkills(conversationDir) {
|
|
16
|
-
const map = new Map();
|
|
17
|
-
for (const dir of [join(conversationDir, "..", "skills"), join(conversationDir, "skills")]) {
|
|
18
|
-
for (const skill of loadSkillsFromDir({ dir, source: dir.includes("/skills") ? "workspace" : "channel" }).skills) {
|
|
19
|
-
map.set(skill.name, skill);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return [...map.values()];
|
|
23
|
-
}
|
|
24
14
|
export function buildAppendSystemPrompt(workspaceDir, conversationKey, memory) {
|
|
25
15
|
return `## Surface
|
|
26
16
|
- You are replying through a Discord harness.
|
package/dist/agent-runner.js
CHANGED
|
@@ -65,7 +65,7 @@ export function wireSessionUpdates(session, runState) {
|
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
export async function runAgentTurn(params) {
|
|
68
|
-
const { ctx, conversationDir, scratchDir, sessionManager, agent, session, runState } = params;
|
|
68
|
+
const { ctx, conversationDir, scratchDir, sessionManager, agent, session, runState, resourceLoader } = params;
|
|
69
69
|
await mkdir(scratchDir, { recursive: true });
|
|
70
70
|
await mkdir(conversationDir, { recursive: true });
|
|
71
71
|
syncLogToSessionManager(sessionManager, conversationDir, ctx.message.messageId);
|
|
@@ -89,6 +89,15 @@ export async function runAgentTurn(params) {
|
|
|
89
89
|
let prompt = `[${ctx.message.userName}]: ${ctx.message.text}`;
|
|
90
90
|
if (otherAttachments.length > 0)
|
|
91
91
|
prompt += `\n\n<discord_attachments>\n${otherAttachments.join("\n")}\n</discord_attachments>`;
|
|
92
|
+
// Reload resources (extensions, skills, prompts, themes) from installed packages
|
|
93
|
+
if (resourceLoader) {
|
|
94
|
+
try {
|
|
95
|
+
await resourceLoader.reload();
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
log.warn("resource reload failed", err instanceof Error ? err.message : String(err));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
92
101
|
await ctx.setTyping(true);
|
|
93
102
|
await ctx.setWorking(true);
|
|
94
103
|
await session.prompt(prompt, imageAttachments.length > 0 ? { images: imageAttachments } : undefined);
|
package/dist/agent.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Agent } from "@mariozechner/pi-agent-core";
|
|
2
|
-
import { AgentSession, AuthStorage, convertToLlm, createCodingTools,
|
|
2
|
+
import { AgentSession, AuthStorage, convertToLlm, createCodingTools, DefaultResourceLoader, ModelRegistry, SessionManager, } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { createDiscordSettingsManager } from "./context.js";
|
|
5
5
|
import { resolveInitialModel, formatModel } from "./agent-models.js";
|
|
6
|
-
import { buildAppendSystemPrompt, getMemory
|
|
6
|
+
import { buildAppendSystemPrompt, getMemory } from "./agent-prompt.js";
|
|
7
7
|
import { createDiscordCustomTools } from "./agent-tools.js";
|
|
8
8
|
import { createSessionOps } from "./agent-session-ops.js";
|
|
9
9
|
import { runAgentTurn, wireSessionUpdates } from "./agent-runner.js";
|
|
@@ -26,19 +26,16 @@ function createRunner(workspaceDir, conversationKey) {
|
|
|
26
26
|
const modelRegistry = ModelRegistry.create(authStorage);
|
|
27
27
|
const sessionManager = SessionManager.open(contextFile, conversationDir);
|
|
28
28
|
const settingsManager = createDiscordSettingsManager(workspaceDir);
|
|
29
|
-
const skills = loadDiscordSkills(conversationDir);
|
|
30
29
|
let appendSystemPrompt = buildAppendSystemPrompt(workspaceDir, conversationKey, getMemory(conversationDir));
|
|
31
|
-
const resourceLoader = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
reload: async () => { },
|
|
41
|
-
};
|
|
30
|
+
const resourceLoader = new DefaultResourceLoader({
|
|
31
|
+
cwd: scratchDir,
|
|
32
|
+
settingsManager,
|
|
33
|
+
additionalSkillPaths: [
|
|
34
|
+
join(workspaceDir, "skills"),
|
|
35
|
+
join(conversationDir, "skills"),
|
|
36
|
+
],
|
|
37
|
+
appendSystemPrompt,
|
|
38
|
+
});
|
|
42
39
|
const runState = {
|
|
43
40
|
ctx: null,
|
|
44
41
|
queue: Promise.resolve(),
|
|
@@ -83,7 +80,7 @@ function createRunner(workspaceDir, conversationKey) {
|
|
|
83
80
|
return {
|
|
84
81
|
async run(ctx) {
|
|
85
82
|
appendSystemPrompt = buildAppendSystemPrompt(workspaceDir, conversationKey, getMemory(conversationDir));
|
|
86
|
-
return runAgentTurn({ ctx, conversationDir, scratchDir, sessionManager, agent, session, runState });
|
|
83
|
+
return runAgentTurn({ ctx, conversationDir, scratchDir, sessionManager, agent, session, runState, resourceLoader });
|
|
87
84
|
},
|
|
88
85
|
abort() {
|
|
89
86
|
void session.abort();
|
package/dist/discord.js
CHANGED
|
@@ -110,13 +110,18 @@ export class DiscordBot {
|
|
|
110
110
|
return;
|
|
111
111
|
const commands = buildSlashCommands();
|
|
112
112
|
const guildId = policy.slashCommands?.guildId;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
try {
|
|
114
|
+
if (guildId) {
|
|
115
|
+
await this.client.application.commands.set(commands, guildId);
|
|
116
|
+
log.info(`registered slash commands in guild ${guildId}`);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
await this.client.application.commands.set(commands);
|
|
120
|
+
log.info("registered global slash commands");
|
|
121
|
+
}
|
|
116
122
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
log.info("registered global slash commands");
|
|
123
|
+
catch (err) {
|
|
124
|
+
log.warn("slash command registration failed (bot will continue without slash commands)", err instanceof Error ? err.message : String(err));
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
async onMessage(message) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-discord-bot",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A small Discord harness built around Pi primitives.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -52,12 +52,14 @@
|
|
|
52
52
|
"prepublishOnly": "npm run build && npm test"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@mariozechner/pi-agent-core": "^0.64.0",
|
|
56
|
-
"@mariozechner/pi-ai": "^0.64.0",
|
|
57
|
-
"@mariozechner/pi-coding-agent": "^0.64.0",
|
|
58
|
-
"@sinclair/typebox": "^0.34.41",
|
|
59
55
|
"discord.js": "^14.19.3"
|
|
60
56
|
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"@mariozechner/pi-agent-core": "*",
|
|
59
|
+
"@mariozechner/pi-ai": "*",
|
|
60
|
+
"@mariozechner/pi-coding-agent": "*",
|
|
61
|
+
"@sinclair/typebox": "*"
|
|
62
|
+
},
|
|
61
63
|
"devDependencies": {
|
|
62
64
|
"@types/node": "^24.3.0",
|
|
63
65
|
"tsx": "^4.19.2",
|