@friendlyrobot/discord-pi-agent 0.21.1 → 0.21.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 +14 -3
- package/dist/agent-model-service.js +132 -0
- package/dist/agent-resource-service.js +70 -0
- package/dist/agent-service.js +189 -0
- package/dist/agent-turn-runner.js +148 -0
- package/dist/config.js +103 -0
- package/dist/debug-print.js +22 -0
- package/dist/discord-attachments.js +148 -0
- package/dist/discord-auth.js +37 -0
- package/dist/discord-gateway-client.js +49 -0
- package/dist/discord-media-resolution.js +107 -0
- package/dist/discord-message-handler.js +189 -0
- package/dist/discord-replies.js +112 -0
- package/dist/discord-typing.js +75 -0
- package/dist/index.js +57 -1904
- package/dist/logger.js +26 -0
- package/dist/markdown-table-transformer.js +138 -0
- package/dist/media-description.js +87 -0
- package/dist/message-chunker.js +38 -0
- package/dist/prompt-context.js +19 -0
- package/dist/prompt-queue.js +37 -0
- package/dist/session-commands.js +281 -0
- package/dist/session-registry.js +73 -0
- package/dist/types.js +1 -0
- package/package.json +4 -5
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { createModuleLogger } from "./logger";
|
|
2
|
+
const logger = createModuleLogger("discord-typing");
|
|
3
|
+
const TYPING_INTERVAL_MS = 9000;
|
|
4
|
+
const typingIntervals = new Map();
|
|
5
|
+
export async function sendTypingSafe(channel, channelKey) {
|
|
6
|
+
try {
|
|
7
|
+
const token = channel.client.token;
|
|
8
|
+
const url = `https://discord.com/api/v10/channels/${channel.id}/typing`;
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
method: "POST",
|
|
11
|
+
headers: { Authorization: `Bot ${token}` },
|
|
12
|
+
});
|
|
13
|
+
if (response.ok) {
|
|
14
|
+
// logger.debug("[TYPING] STATUS UPDATED OK");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (response.status === 429) {
|
|
18
|
+
const body = await response.text();
|
|
19
|
+
let retryMs = 3_000;
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(body);
|
|
22
|
+
if (typeof parsed.retry_after === "number") {
|
|
23
|
+
retryMs = parsed.retry_after * 1_000 + 500;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// ignore parse errors
|
|
28
|
+
}
|
|
29
|
+
logger.warn({ channelKey, retryMs, response: body }, `[TYPING] 429, retrying after ${retryMs}ms delay`);
|
|
30
|
+
await new Promise((resolve) => setTimeout(resolve, retryMs));
|
|
31
|
+
await fetch(url, {
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: { Authorization: `Bot ${token}` },
|
|
34
|
+
});
|
|
35
|
+
logger.warn({ channelKey }, "[TYPING] retry done");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
logger.warn({ channelKey, status: response.status }, "[TYPING] unexpected status");
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
logger.error({ channelKey, error }, "[TYPING] FAILED");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function startTypingForChannel(channel, channelKey) {
|
|
45
|
+
const existing = typingIntervals.get(channelKey);
|
|
46
|
+
if (existing) {
|
|
47
|
+
existing.refs += 1;
|
|
48
|
+
// logger.debug(
|
|
49
|
+
// { channelKey, refs: existing.refs },
|
|
50
|
+
// "[TYPING] ref++ (reusing existing interval)",
|
|
51
|
+
// );
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
logger.debug("[TYPING] started new interval");
|
|
55
|
+
void sendTypingSafe(channel, channelKey);
|
|
56
|
+
const interval = setInterval(() => {
|
|
57
|
+
void sendTypingSafe(channel, channelKey);
|
|
58
|
+
}, TYPING_INTERVAL_MS);
|
|
59
|
+
typingIntervals.set(channelKey, { interval, refs: 1 });
|
|
60
|
+
}
|
|
61
|
+
export function stopTypingForChannel(channelKey) {
|
|
62
|
+
const entry = typingIntervals.get(channelKey);
|
|
63
|
+
if (!entry) {
|
|
64
|
+
// logger.debug({ channelKey }, "[TYPING] stop called but no entry found");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
entry.refs -= 1;
|
|
68
|
+
if (entry.refs <= 0) {
|
|
69
|
+
clearInterval(entry.interval);
|
|
70
|
+
typingIntervals.delete(channelKey);
|
|
71
|
+
// logger.debug("[TYPING] interval cleared (refs hit 0)");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// logger.debug("[TYPING] ref-- (interval still active)");
|
|
75
|
+
}
|