@4via6/relay 1.0.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/.env.example +50 -0
- package/README.md +253 -0
- package/dist/auth.d.ts +3 -0
- package/dist/auth.js +32 -0
- package/dist/auth.js.map +1 -0
- package/dist/bot.d.ts +2 -0
- package/dist/bot.js +14 -0
- package/dist/bot.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/admin.d.ts +2 -0
- package/dist/commands/admin.js +420 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/chat.d.ts +2 -0
- package/dist/commands/chat.js +80 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/files.d.ts +2 -0
- package/dist/commands/files.js +162 -0
- package/dist/commands/files.js.map +1 -0
- package/dist/commands/history.d.ts +2 -0
- package/dist/commands/history.js +152 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.js +21 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/mcp.d.ts +2 -0
- package/dist/commands/mcp.js +105 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/media.d.ts +2 -0
- package/dist/commands/media.js +248 -0
- package/dist/commands/media.js.map +1 -0
- package/dist/commands/monitor.d.ts +2 -0
- package/dist/commands/monitor.js +136 -0
- package/dist/commands/monitor.js.map +1 -0
- package/dist/commands/session.d.ts +2 -0
- package/dist/commands/session.js +114 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/shell.d.ts +2 -0
- package/dist/commands/shell.js +90 -0
- package/dist/commands/shell.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/claude.d.ts +52 -0
- package/dist/providers/claude.js +449 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex.d.ts +45 -0
- package/dist/providers/codex.js +400 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.js +40 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/opencode.d.ts +40 -0
- package/dist/providers/opencode.js +498 -0
- package/dist/providers/opencode.js.map +1 -0
- package/dist/providers/types.d.ts +173 -0
- package/dist/providers/types.js +6 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/session.d.ts +10 -0
- package/dist/session.js +65 -0
- package/dist/session.js.map +1 -0
- package/dist/utils/chunker.d.ts +1 -0
- package/dist/utils/chunker.js +24 -0
- package/dist/utils/chunker.js.map +1 -0
- package/dist/utils/errors.d.ts +12 -0
- package/dist/utils/errors.js +85 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/files.d.ts +15 -0
- package/dist/utils/files.js +81 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/html.d.ts +4 -0
- package/dist/utils/html.js +10 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/media.d.ts +15 -0
- package/dist/utils/media.js +103 -0
- package/dist/utils/media.js.map +1 -0
- package/dist/utils/store.d.ts +15 -0
- package/dist/utils/store.js +44 -0
- package/dist/utils/store.js.map +1 -0
- package/dist/utils/stream.d.ts +21 -0
- package/dist/utils/stream.js +149 -0
- package/dist/utils/stream.js.map +1 -0
- package/dist/utils/stt.d.ts +7 -0
- package/dist/utils/stt.js +118 -0
- package/dist/utils/stt.js.map +1 -0
- package/dist/utils/system-prompt.d.ts +5 -0
- package/dist/utils/system-prompt.js +64 -0
- package/dist/utils/system-prompt.js.map +1 -0
- package/dist/utils/timeout.d.ts +2 -0
- package/dist/utils/timeout.js +18 -0
- package/dist/utils/timeout.js.map +1 -0
- package/docs/commands.md +351 -0
- package/docs/configuration.md +160 -0
- package/docs/features.md +443 -0
- package/docs/getting-started.md +102 -0
- package/docs/providers.md +236 -0
- package/docs/troubleshooting.md +287 -0
- package/package.json +54 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { getProvider } from "../providers/index.js";
|
|
2
|
+
import { getOrCreateSession, getSelectedModel } from "../session.js";
|
|
3
|
+
import { chunkMessage } from "../utils/chunker.js";
|
|
4
|
+
import { downloadTelegramFile, downloadTelegramFileBuffer } from "../utils/media.js";
|
|
5
|
+
import { transcribeAudio, isSttAvailable } from "../utils/stt.js";
|
|
6
|
+
import { isStreamingEnabled, streamPrompt } from "../utils/stream.js";
|
|
7
|
+
import { getSystemPrompt } from "../utils/system-prompt.js";
|
|
8
|
+
import { formatCatchError, EMPTY_RESPONSE_MSG } from "../utils/errors.js";
|
|
9
|
+
import { withTimeout, getPromptTimeout } from "../utils/timeout.js";
|
|
10
|
+
import { extractFileParts, sendResponseFiles } from "../utils/files.js";
|
|
11
|
+
import { readFileSync } from "fs";
|
|
12
|
+
const botToken = process.env.BOT_TOKEN ?? "";
|
|
13
|
+
export function registerMediaHandlers(bot) {
|
|
14
|
+
bot.on("message:document", async (ctx) => {
|
|
15
|
+
try {
|
|
16
|
+
const doc = ctx.message.document;
|
|
17
|
+
const file = await ctx.getFile();
|
|
18
|
+
const fileName = doc.file_name ?? `file_${Date.now()}`;
|
|
19
|
+
await ctx.replyWithChatAction("typing");
|
|
20
|
+
const localPath = await downloadTelegramFile(botToken, file.file_path, fileName);
|
|
21
|
+
const caption = ctx.message.caption ?? `I've shared a file: ${fileName}. Please review it.`;
|
|
22
|
+
const isTextFile = isTextMime(doc.mime_type) || isTextExtension(fileName);
|
|
23
|
+
let promptText;
|
|
24
|
+
if (isTextFile) {
|
|
25
|
+
const content = readFileSync(localPath, "utf-8");
|
|
26
|
+
if (content.length <= 500_000) {
|
|
27
|
+
promptText = `${caption}\n\nFile: ${fileName}\n\`\`\`\n${content}\n\`\`\``;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// Chunked: first 100K chars + last 10K chars for very large files
|
|
31
|
+
const head = content.slice(0, 100_000);
|
|
32
|
+
const tail = content.slice(-10_000);
|
|
33
|
+
const omitted = content.length - 110_000;
|
|
34
|
+
promptText = `${caption}\n\nFile: ${fileName} (${content.length} chars, truncated)\n\`\`\`\n${head}\n\n... [${omitted} characters omitted] ...\n\n${tail}\n\`\`\``;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
promptText = `${caption}\n\n(Binary file: ${fileName}, ${doc.file_size ?? "unknown"} bytes)`;
|
|
39
|
+
}
|
|
40
|
+
const sessionId = await getOrCreateSession();
|
|
41
|
+
const provider = getProvider();
|
|
42
|
+
const model = getSelectedModel();
|
|
43
|
+
const system = getSystemPrompt();
|
|
44
|
+
const result = await withTimeout(provider.prompt(sessionId, promptText, {
|
|
45
|
+
parts: [{ type: "text", text: promptText }],
|
|
46
|
+
...(model && { model }),
|
|
47
|
+
system,
|
|
48
|
+
}), getPromptTimeout(), "Prompt");
|
|
49
|
+
if (!result.text.trim() || result.text === "(empty response)") {
|
|
50
|
+
await ctx.reply(EMPTY_RESPONSE_MSG, { parse_mode: "HTML" });
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
await sendTextChunks(ctx, result.text);
|
|
54
|
+
await sendFiles(ctx, result.parts);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
await ctx.reply(formatCatchError(err, "handling file"), { parse_mode: "HTML" });
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
bot.on("message:photo", async (ctx) => {
|
|
61
|
+
try {
|
|
62
|
+
const photos = ctx.message.photo;
|
|
63
|
+
const largest = photos[photos.length - 1];
|
|
64
|
+
const file = await ctx.api.getFile(largest.file_id);
|
|
65
|
+
const fileName = `photo_${Date.now()}.jpg`;
|
|
66
|
+
await ctx.replyWithChatAction("typing");
|
|
67
|
+
const buffer = await downloadTelegramFileBuffer(botToken, file.file_path);
|
|
68
|
+
const caption = ctx.message.caption ?? "I've shared a photo. Please review it.";
|
|
69
|
+
// Send as FilePartInput with base64 data URL for vision models
|
|
70
|
+
const base64 = buffer.toString("base64");
|
|
71
|
+
const dataUrl = `data:image/jpeg;base64,${base64}`;
|
|
72
|
+
const parts = [
|
|
73
|
+
{ type: "text", text: caption },
|
|
74
|
+
{
|
|
75
|
+
type: "file",
|
|
76
|
+
mime: "image/jpeg",
|
|
77
|
+
filename: fileName,
|
|
78
|
+
url: dataUrl,
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
// Also save locally for reference
|
|
82
|
+
await downloadTelegramFile(botToken, file.file_path, fileName);
|
|
83
|
+
const sessionId = await getOrCreateSession();
|
|
84
|
+
const model = getSelectedModel();
|
|
85
|
+
const system = getSystemPrompt();
|
|
86
|
+
const provider = getProvider();
|
|
87
|
+
if (isStreamingEnabled() && provider.promptStream) {
|
|
88
|
+
await streamPrompt({ ctx, sessionId, parts, model, system });
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const result = await withTimeout(provider.prompt(sessionId, caption, {
|
|
92
|
+
parts,
|
|
93
|
+
...(model && { model }),
|
|
94
|
+
system,
|
|
95
|
+
}), getPromptTimeout(), "Prompt");
|
|
96
|
+
if (!result.text.trim() || result.text === "(empty response)") {
|
|
97
|
+
await ctx.reply(EMPTY_RESPONSE_MSG, { parse_mode: "HTML" });
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
await sendTextChunks(ctx, result.text);
|
|
101
|
+
await sendFiles(ctx, result.parts);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
await ctx.reply(formatCatchError(err, "handling photo"), { parse_mode: "HTML" });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
bot.on("message:voice", async (ctx) => {
|
|
109
|
+
if (!isSttAvailable()) {
|
|
110
|
+
await ctx.reply("Voice messages not supported. Configure GROQ_API_KEY, OPENAI_API_KEY, or ASSEMBLYAI_API_KEY.");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
await ctx.replyWithChatAction("typing");
|
|
115
|
+
const file = await ctx.getFile();
|
|
116
|
+
const fileName = `voice_${Date.now()}.ogg`;
|
|
117
|
+
const buffer = await downloadTelegramFileBuffer(botToken, file.file_path);
|
|
118
|
+
const result = await transcribeAudio(buffer, fileName);
|
|
119
|
+
if (!result.text || result.text.trim().length === 0) {
|
|
120
|
+
await ctx.reply("Could not transcribe voice message (empty result).");
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const sessionId = await getOrCreateSession();
|
|
124
|
+
const model = getSelectedModel();
|
|
125
|
+
const system = getSystemPrompt();
|
|
126
|
+
const provider = getProvider();
|
|
127
|
+
const promptParts = [{ type: "text", text: result.text }];
|
|
128
|
+
if (isStreamingEnabled() && provider.promptStream) {
|
|
129
|
+
await streamPrompt({ ctx, sessionId, parts: promptParts, model, system });
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
await ctx.replyWithChatAction("typing");
|
|
133
|
+
const promptResult = await withTimeout(provider.prompt(sessionId, result.text, {
|
|
134
|
+
parts: promptParts,
|
|
135
|
+
...(model && { model }),
|
|
136
|
+
system,
|
|
137
|
+
}), getPromptTimeout(), "Prompt");
|
|
138
|
+
if (!promptResult.text.trim() || promptResult.text === "(empty response)") {
|
|
139
|
+
await ctx.reply(EMPTY_RESPONSE_MSG, { parse_mode: "HTML" });
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
await sendTextChunks(ctx, promptResult.text);
|
|
143
|
+
await sendFiles(ctx, promptResult.parts);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
await ctx.reply(formatCatchError(err, "handling voice message"), { parse_mode: "HTML" });
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
bot.on("message:audio", async (ctx) => {
|
|
151
|
+
try {
|
|
152
|
+
const audio = ctx.message.audio;
|
|
153
|
+
const file = await ctx.getFile();
|
|
154
|
+
const fileName = audio.file_name ?? `audio_${Date.now()}.mp3`;
|
|
155
|
+
await ctx.replyWithChatAction("typing");
|
|
156
|
+
if (isSttAvailable()) {
|
|
157
|
+
const buffer = await downloadTelegramFileBuffer(botToken, file.file_path);
|
|
158
|
+
const result = await transcribeAudio(buffer, fileName);
|
|
159
|
+
if (result.text && result.text.trim().length > 0) {
|
|
160
|
+
await ctx.replyWithChatAction("typing");
|
|
161
|
+
const sessionId = await getOrCreateSession();
|
|
162
|
+
const provider = getProvider();
|
|
163
|
+
const model = getSelectedModel();
|
|
164
|
+
const system = getSystemPrompt();
|
|
165
|
+
const promptResult = await withTimeout(provider.prompt(sessionId, result.text, {
|
|
166
|
+
parts: [{ type: "text", text: result.text }],
|
|
167
|
+
...(model && { model }),
|
|
168
|
+
system,
|
|
169
|
+
}), getPromptTimeout(), "Prompt");
|
|
170
|
+
if (!promptResult.text.trim() || promptResult.text === "(empty response)") {
|
|
171
|
+
await ctx.reply(EMPTY_RESPONSE_MSG, { parse_mode: "HTML" });
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
await sendTextChunks(ctx, promptResult.text);
|
|
175
|
+
await sendFiles(ctx, promptResult.parts);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Fallback: download and reference as file
|
|
180
|
+
await downloadTelegramFile(botToken, file.file_path, fileName);
|
|
181
|
+
const caption = ctx.message.caption ?? `Audio file: ${fileName}`;
|
|
182
|
+
const sessionId = await getOrCreateSession();
|
|
183
|
+
const provider = getProvider();
|
|
184
|
+
const model = getSelectedModel();
|
|
185
|
+
const system = getSystemPrompt();
|
|
186
|
+
const promptResult = await withTimeout(provider.prompt(sessionId, `${caption}\n\n(Audio file: ${fileName})`, {
|
|
187
|
+
parts: [
|
|
188
|
+
{
|
|
189
|
+
type: "text",
|
|
190
|
+
text: `${caption}\n\n(Audio file: ${fileName})`,
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
...(model && { model }),
|
|
194
|
+
system,
|
|
195
|
+
}), getPromptTimeout(), "Prompt");
|
|
196
|
+
if (!promptResult.text.trim() || promptResult.text === "(empty response)") {
|
|
197
|
+
await ctx.reply(EMPTY_RESPONSE_MSG, { parse_mode: "HTML" });
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
await sendTextChunks(ctx, promptResult.text);
|
|
201
|
+
await sendFiles(ctx, promptResult.parts);
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
await ctx.reply(formatCatchError(err, "handling audio"), { parse_mode: "HTML" });
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
function isTextMime(mime) {
|
|
209
|
+
if (!mime)
|
|
210
|
+
return false;
|
|
211
|
+
return (mime.startsWith("text/") ||
|
|
212
|
+
mime === "application/json" ||
|
|
213
|
+
mime === "application/javascript" ||
|
|
214
|
+
mime === "application/typescript" ||
|
|
215
|
+
mime === "application/xml" ||
|
|
216
|
+
mime === "application/yaml" ||
|
|
217
|
+
mime === "application/x-yaml");
|
|
218
|
+
}
|
|
219
|
+
async function sendTextChunks(ctx, text) {
|
|
220
|
+
const chunks = chunkMessage(text);
|
|
221
|
+
for (const chunk of chunks) {
|
|
222
|
+
try {
|
|
223
|
+
await ctx.reply(chunk, { parse_mode: "Markdown" });
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
await ctx.reply(chunk);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
async function sendFiles(ctx, parts) {
|
|
231
|
+
if (!parts)
|
|
232
|
+
return;
|
|
233
|
+
const files = extractFileParts(parts);
|
|
234
|
+
if (files.length > 0) {
|
|
235
|
+
await sendResponseFiles(ctx, files);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function isTextExtension(name) {
|
|
239
|
+
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
240
|
+
return [
|
|
241
|
+
"ts", "tsx", "js", "jsx", "json", "md", "txt", "py", "go", "rs",
|
|
242
|
+
"java", "c", "cpp", "h", "hpp", "css", "html", "xml", "yaml", "yml",
|
|
243
|
+
"toml", "ini", "cfg", "sh", "bash", "zsh", "sql", "rb", "php",
|
|
244
|
+
"swift", "kt", "scala", "lua", "r", "csv", "env", "gitignore",
|
|
245
|
+
"dockerfile", "makefile",
|
|
246
|
+
].includes(ext);
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/commands/media.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { InputFile } from "grammy";
|
|
2
|
+
import { getProvider } from "../providers/index.js";
|
|
3
|
+
import { getActiveSessionId, setActiveSessionId } from "../session.js";
|
|
4
|
+
import { chunkMessage } from "../utils/chunker.js";
|
|
5
|
+
import { formatCatchError } from "../utils/errors.js";
|
|
6
|
+
import { escapeHtml } from "../utils/html.js";
|
|
7
|
+
export function registerMonitorCommands(bot) {
|
|
8
|
+
bot.command("todo", async (ctx) => {
|
|
9
|
+
try {
|
|
10
|
+
const sessionId = getActiveSessionId();
|
|
11
|
+
if (!sessionId) {
|
|
12
|
+
await ctx.reply("No active session. Use /new to create one.");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const provider = getProvider();
|
|
16
|
+
const todos = await provider.getTodos(sessionId);
|
|
17
|
+
if (todos === null) {
|
|
18
|
+
await ctx.reply(`Todo list is not supported by the ${provider.name} provider.`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (todos.length === 0) {
|
|
22
|
+
await ctx.reply("No tasks in this session.");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const lines = todos.map((t) => {
|
|
26
|
+
const icon = statusIcon(t.status);
|
|
27
|
+
const priority = t.priority ? ` [${t.priority}]` : "";
|
|
28
|
+
return `${icon} ${escapeHtml(t.content)}${priority}`;
|
|
29
|
+
});
|
|
30
|
+
const text = `<b>Todo List</b> (${todos.length} item${todos.length === 1 ? "" : "s"})\n\n` +
|
|
31
|
+
lines.join("\n");
|
|
32
|
+
const chunks = chunkMessage(text);
|
|
33
|
+
for (const chunk of chunks) {
|
|
34
|
+
await ctx.reply(chunk, { parse_mode: "HTML" });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
await ctx.reply(formatCatchError(err, "fetching todo list"), { parse_mode: "HTML" });
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
bot.command("diff", async (ctx) => {
|
|
42
|
+
try {
|
|
43
|
+
const sessionId = getActiveSessionId();
|
|
44
|
+
if (!sessionId) {
|
|
45
|
+
await ctx.reply("No active session. Use /new to create one.");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const provider = getProvider();
|
|
49
|
+
const diffs = await provider.getDiff(sessionId);
|
|
50
|
+
if (diffs === null) {
|
|
51
|
+
await ctx.reply(`Diff is not supported by the ${provider.name} provider.`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (diffs.length === 0) {
|
|
55
|
+
await ctx.reply("No changes in this session.");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Build summary
|
|
59
|
+
let totalAdded = 0;
|
|
60
|
+
let totalDeleted = 0;
|
|
61
|
+
for (const d of diffs) {
|
|
62
|
+
totalAdded += d.additions;
|
|
63
|
+
totalDeleted += d.deletions;
|
|
64
|
+
}
|
|
65
|
+
const arg = ctx.match?.trim();
|
|
66
|
+
// "full" → send before/after content as file
|
|
67
|
+
if (arg === "full") {
|
|
68
|
+
const fullText = diffs
|
|
69
|
+
.map((d) => {
|
|
70
|
+
let section = `=== ${d.file} === +${d.additions} -${d.deletions}\n`;
|
|
71
|
+
if (d.after) {
|
|
72
|
+
section += `--- before\n${d.before ?? "(new file)"}\n+++ after\n${d.after}\n`;
|
|
73
|
+
}
|
|
74
|
+
return section;
|
|
75
|
+
})
|
|
76
|
+
.join("\n\n");
|
|
77
|
+
const buffer = Buffer.from(fullText, "utf-8");
|
|
78
|
+
await ctx.replyWithDocument(new InputFile(buffer, "session-diff.txt"));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Default: compact summary
|
|
82
|
+
const fileLines = diffs.map((d) => `<code>${escapeHtml(d.file)}</code> +${d.additions} -${d.deletions}`);
|
|
83
|
+
const text = `<b>Session Diff</b> ` +
|
|
84
|
+
`${diffs.length} file${diffs.length === 1 ? "" : "s"} changed ` +
|
|
85
|
+
`<code>+${totalAdded} -${totalDeleted}</code>\n\n` +
|
|
86
|
+
fileLines.join("\n") +
|
|
87
|
+
`\n\n<i>Use /diff full to download full content</i>`;
|
|
88
|
+
const chunks = chunkMessage(text);
|
|
89
|
+
for (const chunk of chunks) {
|
|
90
|
+
await ctx.reply(chunk, { parse_mode: "HTML" });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
await ctx.reply(formatCatchError(err, "fetching diff"), { parse_mode: "HTML" });
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
bot.command("fork", async (ctx) => {
|
|
98
|
+
try {
|
|
99
|
+
const sessionId = getActiveSessionId();
|
|
100
|
+
if (!sessionId) {
|
|
101
|
+
await ctx.reply("No active session. Use /new to create one.");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const messageID = ctx.match?.trim() || undefined;
|
|
105
|
+
const provider = getProvider();
|
|
106
|
+
const forked = await provider.forkSession(sessionId, messageID);
|
|
107
|
+
if (!forked) {
|
|
108
|
+
await ctx.reply(`Forking is not supported by the ${provider.name} provider.`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
setActiveSessionId(forked.id);
|
|
112
|
+
await ctx.reply(`<b>Session forked</b>\n\n` +
|
|
113
|
+
`<b>Title:</b> ${escapeHtml(forked.title ?? "Untitled")}\n` +
|
|
114
|
+
`<b>ID:</b> <code>${forked.id}</code>\n` +
|
|
115
|
+
(messageID ? `<b>From message:</b> <code>${messageID}</code>\n` : "") +
|
|
116
|
+
`\nSwitched to the forked session.`, { parse_mode: "HTML" });
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
await ctx.reply(formatCatchError(err, "forking session"), { parse_mode: "HTML" });
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function statusIcon(status) {
|
|
124
|
+
switch (status) {
|
|
125
|
+
case "completed":
|
|
126
|
+
return "\u2705";
|
|
127
|
+
case "in_progress":
|
|
128
|
+
return "\u23f3";
|
|
129
|
+
case "cancelled":
|
|
130
|
+
return "\u274c";
|
|
131
|
+
case "pending":
|
|
132
|
+
default:
|
|
133
|
+
return "\u2b1c";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/commands/monitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { getProvider } from "../providers/index.js";
|
|
2
|
+
import { getActiveSessionId, setActiveSessionId, clearActiveSession, } from "../session.js";
|
|
3
|
+
import { formatCatchError } from "../utils/errors.js";
|
|
4
|
+
export function registerSessionCommands(bot) {
|
|
5
|
+
bot.command("new", async (ctx) => {
|
|
6
|
+
try {
|
|
7
|
+
const title = ctx.match || "Telegram Session";
|
|
8
|
+
const provider = getProvider();
|
|
9
|
+
const session = await provider.createSession(title);
|
|
10
|
+
setActiveSessionId(session.id);
|
|
11
|
+
await ctx.reply(`Session created!\nTitle: **${session.title ?? title}**\nID: \`${session.id}\``, { parse_mode: "Markdown" });
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
await ctx.reply(formatCatchError(err, "creating session"), { parse_mode: "HTML" });
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
bot.command("sessions", async (ctx) => {
|
|
18
|
+
try {
|
|
19
|
+
const provider = getProvider();
|
|
20
|
+
const sessions = await provider.listSessions();
|
|
21
|
+
if (sessions.length === 0) {
|
|
22
|
+
await ctx.reply("No sessions found.");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const activeId = getActiveSessionId();
|
|
26
|
+
const lines = sessions
|
|
27
|
+
.sort((a, b) => (b.lastModified ?? 0) - (a.lastModified ?? 0))
|
|
28
|
+
.map((s, i) => {
|
|
29
|
+
const marker = s.id === activeId ? " ← active" : "";
|
|
30
|
+
const date = s.lastModified
|
|
31
|
+
? new Date(s.lastModified).toLocaleDateString()
|
|
32
|
+
: "";
|
|
33
|
+
return `${i + 1}. **${s.title || "Untitled"}**\n ID: \`${s.id}\`${date ? ` | ${date}` : ""}${marker}`;
|
|
34
|
+
})
|
|
35
|
+
.join("\n\n");
|
|
36
|
+
const text = activeId
|
|
37
|
+
? `Active: \`${activeId}\`\n\n${lines}`
|
|
38
|
+
: lines;
|
|
39
|
+
try {
|
|
40
|
+
await ctx.reply(text, { parse_mode: "Markdown" });
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
await ctx.reply(text);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
await ctx.reply(formatCatchError(err, "listing sessions"), { parse_mode: "HTML" });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
bot.command("switch", async (ctx) => {
|
|
51
|
+
const id = ctx.match?.trim();
|
|
52
|
+
if (!id) {
|
|
53
|
+
await ctx.reply("Usage: /switch <session-id>");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const provider = getProvider();
|
|
58
|
+
const session = await provider.getSession(id);
|
|
59
|
+
if (!session) {
|
|
60
|
+
await ctx.reply(`Session \`${id}\` not found.`, { parse_mode: "Markdown" });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
setActiveSessionId(id);
|
|
64
|
+
await ctx.reply(`Switched to session: **${session.title ?? "Untitled"}** (\`${id}\`)`, { parse_mode: "Markdown" });
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
await ctx.reply(formatCatchError(err, "switching session"), { parse_mode: "HTML" });
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
bot.command("delete", async (ctx) => {
|
|
71
|
+
const id = ctx.match?.trim();
|
|
72
|
+
if (!id) {
|
|
73
|
+
await ctx.reply("Usage: /delete <session-id>");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const provider = getProvider();
|
|
78
|
+
const deleted = await provider.deleteSession(id);
|
|
79
|
+
if (!deleted) {
|
|
80
|
+
await ctx.reply(`Could not delete session. This may not be supported by the ${provider.name} provider.`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (getActiveSessionId() === id) {
|
|
84
|
+
clearActiveSession();
|
|
85
|
+
}
|
|
86
|
+
await ctx.reply(`Session \`${id}\` deleted.`, { parse_mode: "Markdown" });
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
await ctx.reply(formatCatchError(err, "deleting session"), { parse_mode: "HTML" });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
bot.command("current", async (ctx) => {
|
|
93
|
+
const activeId = getActiveSessionId();
|
|
94
|
+
if (!activeId) {
|
|
95
|
+
await ctx.reply("No active session. Send a message or use /new to create one.");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const provider = getProvider();
|
|
100
|
+
const session = await provider.getSession(activeId);
|
|
101
|
+
if (!session) {
|
|
102
|
+
await ctx.reply(`Active session \`${activeId}\` (details not available)`, {
|
|
103
|
+
parse_mode: "Markdown",
|
|
104
|
+
});
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
await ctx.reply(`**${session.title ?? "Untitled"}**\nID: \`${session.id}\``, { parse_mode: "Markdown" });
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
await ctx.reply(formatCatchError(err, "fetching session"), { parse_mode: "HTML" });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { getProvider } from "../providers/index.js";
|
|
2
|
+
import { getOrCreateSession } from "../session.js";
|
|
3
|
+
import { chunkMessage } from "../utils/chunker.js";
|
|
4
|
+
import { formatCatchError } from "../utils/errors.js";
|
|
5
|
+
import { escapeHtml } from "../utils/html.js";
|
|
6
|
+
export function registerShellCommands(bot) {
|
|
7
|
+
bot.command("shell", async (ctx) => {
|
|
8
|
+
const command = ctx.match?.trim();
|
|
9
|
+
if (!command) {
|
|
10
|
+
await ctx.reply("Usage: /shell <command>");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
await ctx.replyWithChatAction("typing");
|
|
15
|
+
const sessionId = await getOrCreateSession();
|
|
16
|
+
const provider = getProvider();
|
|
17
|
+
const result = await provider.shell(sessionId, command);
|
|
18
|
+
if (result === null) {
|
|
19
|
+
await ctx.reply(`Shell commands are not directly supported by the ${provider.name} provider.`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
await ctx.reply(result);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
await ctx.reply(formatCatchError(err, "running shell command"), { parse_mode: "HTML" });
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
bot.command("cmd", async (ctx) => {
|
|
29
|
+
const input = ctx.match?.trim();
|
|
30
|
+
if (!input) {
|
|
31
|
+
await ctx.reply("Usage: /cmd <command> [arguments]");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const spaceIdx = input.indexOf(" ");
|
|
35
|
+
const command = spaceIdx === -1 ? input : input.slice(0, spaceIdx);
|
|
36
|
+
const args = spaceIdx === -1 ? "" : input.slice(spaceIdx + 1);
|
|
37
|
+
try {
|
|
38
|
+
await ctx.replyWithChatAction("typing");
|
|
39
|
+
const sessionId = await getOrCreateSession();
|
|
40
|
+
const provider = getProvider();
|
|
41
|
+
const result = await provider.runCommand(sessionId, command, args);
|
|
42
|
+
if (result === null) {
|
|
43
|
+
await ctx.reply(`Custom commands are not supported by the ${provider.name} provider.`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const chunks = chunkMessage(result.text);
|
|
47
|
+
for (const chunk of chunks) {
|
|
48
|
+
try {
|
|
49
|
+
await ctx.reply(chunk, { parse_mode: "Markdown" });
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
await ctx.reply(chunk);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
await ctx.reply(formatCatchError(err, "running command"), { parse_mode: "HTML" });
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
bot.command("commands", async (ctx) => {
|
|
61
|
+
try {
|
|
62
|
+
const provider = getProvider();
|
|
63
|
+
const commands = await provider.getCommands();
|
|
64
|
+
if (commands === null) {
|
|
65
|
+
await ctx.reply(`Command listing is not supported by the ${provider.name} provider.`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (commands.length === 0) {
|
|
69
|
+
await ctx.reply("No commands available.");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const text = `<b>Commands</b> (${commands.length})\n` +
|
|
73
|
+
`<i>Use with /cmd <command></i>\n\n` +
|
|
74
|
+
commands
|
|
75
|
+
.map((c) => {
|
|
76
|
+
const desc = c.description ? ` — ${escapeHtml(c.description)}` : "";
|
|
77
|
+
return `<code>${escapeHtml(c.name)}</code>${desc}`;
|
|
78
|
+
})
|
|
79
|
+
.join("\n");
|
|
80
|
+
const chunks = chunkMessage(text);
|
|
81
|
+
for (const chunk of chunks) {
|
|
82
|
+
await ctx.reply(chunk, { parse_mode: "HTML" });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
await ctx.reply(formatCatchError(err, "listing commands"), { parse_mode: "HTML" });
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/commands/shell.ts"],"names":[],"mappings":"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"}
|