alvin-bot 5.6.2 → 5.8.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/CHANGELOG.md +29 -0
- package/README.md +1 -1
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -130
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -443
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -0
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1831
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,317 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom Tool Registration — Users define their own tools via Markdown.
|
|
3
|
-
*
|
|
4
|
-
* Configuration via TOOLS.md (Markdown format):
|
|
5
|
-
*
|
|
6
|
-
* ## tool_name
|
|
7
|
-
* Tool description (first line after heading)
|
|
8
|
-
* ```
|
|
9
|
-
* shell command here
|
|
10
|
-
* ```
|
|
11
|
-
* **Type:** http (optional, default: shell)
|
|
12
|
-
* **URL:** https://example.com/api (for HTTP tools)
|
|
13
|
-
* **Method:** GET|POST|PUT|DELETE (default: GET)
|
|
14
|
-
* **Headers:** Key: Value (one per line)
|
|
15
|
-
* **Body:** request body
|
|
16
|
-
* **Timeout:** 30s, 5m, or milliseconds
|
|
17
|
-
* **Parameters:**
|
|
18
|
-
* - `name` (type, required): description
|
|
19
|
-
*
|
|
20
|
-
* Legacy: Also supports docs/tools.json as fallback.
|
|
21
|
-
*/
|
|
22
|
-
import fs from "fs";
|
|
23
|
-
import { execSync } from "child_process";
|
|
24
|
-
import { isSelfRestartCommand, scheduleGracefulRestart } from "./restart.js";
|
|
25
|
-
import { TOOLS_MD, TOOLS_JSON, TOOLS_EXAMPLE_MD, TOOLS_EXAMPLE_JSON } from "../paths.js";
|
|
26
|
-
// Auto-initialize TOOLS.md from example if missing (prefer MD over JSON)
|
|
27
|
-
if (!fs.existsSync(TOOLS_MD) && fs.existsSync(TOOLS_EXAMPLE_MD)) {
|
|
28
|
-
fs.copyFileSync(TOOLS_EXAMPLE_MD, TOOLS_MD);
|
|
29
|
-
}
|
|
30
|
-
// Legacy fallback: also init tools.json if someone depends on it
|
|
31
|
-
if (!fs.existsSync(TOOLS_JSON) && fs.existsSync(TOOLS_EXAMPLE_JSON)) {
|
|
32
|
-
fs.copyFileSync(TOOLS_EXAMPLE_JSON, TOOLS_JSON);
|
|
33
|
-
}
|
|
34
|
-
// ── Markdown Parser ─────────────────────────────────────
|
|
35
|
-
function parseTimeout(value) {
|
|
36
|
-
const trimmed = value.trim().toLowerCase();
|
|
37
|
-
const match = trimmed.match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);
|
|
38
|
-
if (!match)
|
|
39
|
-
return 30000;
|
|
40
|
-
const num = parseFloat(match[1]);
|
|
41
|
-
switch (match[2]) {
|
|
42
|
-
case "h": return num * 3600000;
|
|
43
|
-
case "m": return num * 60000;
|
|
44
|
-
case "s": return num * 1000;
|
|
45
|
-
case "ms": return num;
|
|
46
|
-
default: return num > 1000 ? num : num * 1000; // bare number: assume seconds if small
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function parseToolsMd(content) {
|
|
50
|
-
const tools = [];
|
|
51
|
-
// Split by ## headings (tool boundaries)
|
|
52
|
-
const sections = content.split(/^## /m).slice(1); // skip preamble before first ##
|
|
53
|
-
for (const section of sections) {
|
|
54
|
-
const lines = section.split("\n");
|
|
55
|
-
const name = lines[0].trim().replace(/\s+/g, "_").toLowerCase();
|
|
56
|
-
if (!name)
|
|
57
|
-
continue;
|
|
58
|
-
const tool = { name, description: "" };
|
|
59
|
-
// First non-empty line after heading = description
|
|
60
|
-
let i = 1;
|
|
61
|
-
while (i < lines.length && !lines[i].trim())
|
|
62
|
-
i++;
|
|
63
|
-
if (i < lines.length && !lines[i].startsWith("```") && !lines[i].startsWith("**")) {
|
|
64
|
-
tool.description = lines[i].trim();
|
|
65
|
-
i++;
|
|
66
|
-
}
|
|
67
|
-
// Parse remaining lines
|
|
68
|
-
let inCodeBlock = false;
|
|
69
|
-
let codeLines = [];
|
|
70
|
-
let inHeaders = false;
|
|
71
|
-
const headerLines = [];
|
|
72
|
-
let inParams = false;
|
|
73
|
-
const paramEntries = [];
|
|
74
|
-
for (; i < lines.length; i++) {
|
|
75
|
-
const line = lines[i];
|
|
76
|
-
// Code block (command)
|
|
77
|
-
if (line.startsWith("```")) {
|
|
78
|
-
if (inCodeBlock) {
|
|
79
|
-
tool.command = codeLines.join("\n").trim();
|
|
80
|
-
inCodeBlock = false;
|
|
81
|
-
codeLines = [];
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
inCodeBlock = true;
|
|
85
|
-
}
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
if (inCodeBlock) {
|
|
89
|
-
codeLines.push(line);
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
// Bold-key fields: **Key:** value
|
|
93
|
-
const boldMatch = line.match(/^\*\*(\w[\w\s]*):\*\*\s*(.*)/);
|
|
94
|
-
if (boldMatch) {
|
|
95
|
-
const key = boldMatch[1].trim().toLowerCase();
|
|
96
|
-
const value = boldMatch[2].trim();
|
|
97
|
-
// End previous multi-line sections
|
|
98
|
-
if (key !== "headers")
|
|
99
|
-
inHeaders = false;
|
|
100
|
-
if (key !== "parameters")
|
|
101
|
-
inParams = false;
|
|
102
|
-
switch (key) {
|
|
103
|
-
case "type":
|
|
104
|
-
tool.type = value.toLowerCase();
|
|
105
|
-
break;
|
|
106
|
-
case "url":
|
|
107
|
-
tool.url = value;
|
|
108
|
-
break;
|
|
109
|
-
case "method":
|
|
110
|
-
tool.method = value.toUpperCase();
|
|
111
|
-
break;
|
|
112
|
-
case "headers":
|
|
113
|
-
inHeaders = true;
|
|
114
|
-
if (value)
|
|
115
|
-
headerLines.push(value);
|
|
116
|
-
break;
|
|
117
|
-
case "body":
|
|
118
|
-
tool.body = value;
|
|
119
|
-
break;
|
|
120
|
-
case "timeout":
|
|
121
|
-
tool.timeout = parseTimeout(value);
|
|
122
|
-
break;
|
|
123
|
-
case "parameters":
|
|
124
|
-
inParams = true;
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
// Header continuation lines (Key: Value)
|
|
130
|
-
if (inHeaders && line.match(/^\s*-?\s*\S+:\s/)) {
|
|
131
|
-
headerLines.push(line.replace(/^\s*-?\s*/, "").trim());
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
else if (inHeaders && line.trim()) {
|
|
135
|
-
inHeaders = false;
|
|
136
|
-
}
|
|
137
|
-
// Parameter entries: - `name` (type, required): description
|
|
138
|
-
if (inParams && line.match(/^\s*-\s*`/)) {
|
|
139
|
-
const paramMatch = line.match(/^\s*-\s*`(\w+)`\s*\(([^)]+)\)\s*:?\s*(.*)/);
|
|
140
|
-
if (paramMatch) {
|
|
141
|
-
const pName = paramMatch[1];
|
|
142
|
-
const pMeta = paramMatch[2];
|
|
143
|
-
const pDesc = paramMatch[3].trim();
|
|
144
|
-
const parts = pMeta.split(",").map(s => s.trim().toLowerCase());
|
|
145
|
-
const pType = parts.find(p => ["string", "number", "boolean", "integer"].includes(p)) || "string";
|
|
146
|
-
const pRequired = parts.includes("required");
|
|
147
|
-
paramEntries.push({ name: pName, type: pType, description: pDesc, required: pRequired });
|
|
148
|
-
}
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
else if (inParams && line.trim() && !line.startsWith(" ")) {
|
|
152
|
-
inParams = false;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
// Assemble headers
|
|
156
|
-
if (headerLines.length > 0) {
|
|
157
|
-
tool.headers = {};
|
|
158
|
-
for (const h of headerLines) {
|
|
159
|
-
const colonIdx = h.indexOf(":");
|
|
160
|
-
if (colonIdx > 0) {
|
|
161
|
-
tool.headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim();
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
// Assemble parameters
|
|
166
|
-
if (paramEntries.length > 0) {
|
|
167
|
-
tool.parameters = {};
|
|
168
|
-
for (const p of paramEntries) {
|
|
169
|
-
tool.parameters[p.name] = { type: p.type, description: p.description, required: p.required };
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
tools.push(tool);
|
|
173
|
-
}
|
|
174
|
-
return tools;
|
|
175
|
-
}
|
|
176
|
-
// ── Config Loading ──────────────────────────────────────
|
|
177
|
-
function loadToolsConfig() {
|
|
178
|
-
// Prefer TOOLS.md (Markdown format)
|
|
179
|
-
if (fs.existsSync(TOOLS_MD)) {
|
|
180
|
-
try {
|
|
181
|
-
const content = fs.readFileSync(TOOLS_MD, "utf-8");
|
|
182
|
-
const tools = parseToolsMd(content);
|
|
183
|
-
return { tools };
|
|
184
|
-
}
|
|
185
|
-
catch {
|
|
186
|
-
// Fall through to JSON
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
// Legacy fallback: docs/tools.json
|
|
190
|
-
if (fs.existsSync(TOOLS_JSON)) {
|
|
191
|
-
try {
|
|
192
|
-
const raw = fs.readFileSync(TOOLS_JSON, "utf-8");
|
|
193
|
-
return JSON.parse(raw);
|
|
194
|
-
}
|
|
195
|
-
catch {
|
|
196
|
-
// ignore
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return { tools: [] };
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Get the path of the active tools config file.
|
|
203
|
-
*/
|
|
204
|
-
export function getToolsConfigPath() {
|
|
205
|
-
if (fs.existsSync(TOOLS_MD))
|
|
206
|
-
return TOOLS_MD;
|
|
207
|
-
return TOOLS_JSON;
|
|
208
|
-
}
|
|
209
|
-
// ── Template Substitution ───────────────────────────────
|
|
210
|
-
function substituteParams(template, params) {
|
|
211
|
-
let result = template;
|
|
212
|
-
for (const [key, value] of Object.entries(params)) {
|
|
213
|
-
result = result.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), String(value));
|
|
214
|
-
}
|
|
215
|
-
return result;
|
|
216
|
-
}
|
|
217
|
-
// ── Execution ───────────────────────────────────────────
|
|
218
|
-
async function executeShellTool(tool, params) {
|
|
219
|
-
if (!tool.command)
|
|
220
|
-
throw new Error("No command defined");
|
|
221
|
-
const cmd = substituteParams(tool.command, params);
|
|
222
|
-
// Intercept self-restart: use graceful internal restart instead of pm2 kill
|
|
223
|
-
if (isSelfRestartCommand(cmd)) {
|
|
224
|
-
scheduleGracefulRestart();
|
|
225
|
-
return "Bot restart scheduled. Grammy will commit the Telegram offset before exiting.";
|
|
226
|
-
}
|
|
227
|
-
try {
|
|
228
|
-
const result = execSync(cmd, {
|
|
229
|
-
stdio: "pipe",
|
|
230
|
-
timeout: tool.timeout || 30000,
|
|
231
|
-
env: process.env,
|
|
232
|
-
});
|
|
233
|
-
return result.toString().trim() || "(no output)";
|
|
234
|
-
}
|
|
235
|
-
catch (err) {
|
|
236
|
-
const error = err;
|
|
237
|
-
throw new Error(error.stderr?.toString()?.trim() || error.message);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
async function executeHttpTool(tool, params) {
|
|
241
|
-
if (!tool.url)
|
|
242
|
-
throw new Error("No URL defined");
|
|
243
|
-
const url = substituteParams(tool.url, params);
|
|
244
|
-
const method = tool.method || "GET";
|
|
245
|
-
const headers = {};
|
|
246
|
-
if (tool.headers) {
|
|
247
|
-
for (const [key, value] of Object.entries(tool.headers)) {
|
|
248
|
-
headers[key] = substituteParams(value, params);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
const fetchOpts = { method, headers };
|
|
252
|
-
if (tool.body && method !== "GET") {
|
|
253
|
-
fetchOpts.body = substituteParams(tool.body, params);
|
|
254
|
-
if (!headers["Content-Type"]) {
|
|
255
|
-
headers["Content-Type"] = "application/json";
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
const controller = new AbortController();
|
|
259
|
-
const timeoutId = setTimeout(() => controller.abort(), tool.timeout || 30000);
|
|
260
|
-
fetchOpts.signal = controller.signal;
|
|
261
|
-
try {
|
|
262
|
-
const response = await fetch(url, fetchOpts);
|
|
263
|
-
clearTimeout(timeoutId);
|
|
264
|
-
const text = await response.text();
|
|
265
|
-
return `HTTP ${response.status}: ${text.slice(0, 2000)}`;
|
|
266
|
-
}
|
|
267
|
-
catch (err) {
|
|
268
|
-
clearTimeout(timeoutId);
|
|
269
|
-
throw err;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
// ── Public API ──────────────────────────────────────────
|
|
273
|
-
/**
|
|
274
|
-
* Get all custom tools for display/registration.
|
|
275
|
-
*/
|
|
276
|
-
export function getCustomTools() {
|
|
277
|
-
const config = loadToolsConfig();
|
|
278
|
-
return config.tools.map(t => ({
|
|
279
|
-
name: t.name,
|
|
280
|
-
description: t.description,
|
|
281
|
-
parameters: t.parameters || {},
|
|
282
|
-
}));
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Execute a custom tool by name.
|
|
286
|
-
*/
|
|
287
|
-
export async function executeCustomTool(name, params) {
|
|
288
|
-
const config = loadToolsConfig();
|
|
289
|
-
const tool = config.tools.find(t => t.name === name);
|
|
290
|
-
if (!tool)
|
|
291
|
-
throw new Error(`Custom tool "${name}" not found`);
|
|
292
|
-
const type = tool.type || (tool.url ? "http" : "shell");
|
|
293
|
-
switch (type) {
|
|
294
|
-
case "http":
|
|
295
|
-
return executeHttpTool(tool, params);
|
|
296
|
-
case "shell":
|
|
297
|
-
default:
|
|
298
|
-
return executeShellTool(tool, params);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* List custom tools for the /tools command.
|
|
303
|
-
*/
|
|
304
|
-
export function listCustomTools() {
|
|
305
|
-
const config = loadToolsConfig();
|
|
306
|
-
return config.tools.map(t => ({
|
|
307
|
-
name: t.name,
|
|
308
|
-
description: t.description,
|
|
309
|
-
type: t.type || (t.url ? "http" : "shell"),
|
|
310
|
-
}));
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Check if custom tools config exists.
|
|
314
|
-
*/
|
|
315
|
-
export function hasCustomTools() {
|
|
316
|
-
return fs.existsSync(TOOLS_MD) || fs.existsSync(TOOLS_JSON);
|
|
317
|
-
}
|
|
1
|
+
const _0x647bdd=_0x103c,_0x1ab7cd=_0x103c;(function(_0x18d588,_0x3c4787){const _0x1e1b7a=_0x103c,_0x14e0b8=_0x103c,_0x3c4d53=_0x18d588();while(!![]){try{const _0x252aef=parseInt(_0x1e1b7a(0xd1))/(-0x225a+0xdd8+0x3b*0x59)+-parseInt(_0x14e0b8(0xbd))/(0x2bc*0x1+0x1b9b+-0x1e55)*(parseInt(_0x14e0b8(0xd3))/(0x265f+0x174+-0x4*0x9f4))+-parseInt(_0x1e1b7a(0xcc))/(0x3*-0x9c1+-0x21*0x61+0xbf*0x38)+parseInt(_0x1e1b7a(0xe2))/(-0x4f3*-0x2+-0x2245+0x1864)+-parseInt(_0x14e0b8(0xc3))/(0x2*-0xbef+-0x8*0x346+0x3214)+parseInt(_0x1e1b7a(0xec))/(0x2c8*0x7+-0x13a+-0x1237)*(-parseInt(_0x1e1b7a(0xf9))/(0x1a49*0x1+0x55*-0x52+0xf9))+-parseInt(_0x1e1b7a(0xc0))/(-0x26ef*-0x1+0x101d+-0x3703)*(-parseInt(_0x14e0b8(0xd5))/(-0x2ef+0x14bf+-0xb6*0x19));if(_0x252aef===_0x3c4787)break;else _0x3c4d53['push'](_0x3c4d53['shift']());}catch(_0x23d5ee){_0x3c4d53['push'](_0x3c4d53['shift']());}}}(_0x3b1e,0x3021*0x3e+-0x80f*-0x67+-0x509*0x119));const _0x5bf9d6=(function(){let _0x50fb81=!![];return function(_0x4a4f23,_0x4cf430){const _0x4246f4=_0x50fb81?function(){const _0x1a6405=_0x103c;if(_0x4cf430){const _0x209662=_0x4cf430[_0x1a6405(0xee)](_0x4a4f23,arguments);return _0x4cf430=null,_0x209662;}}:function(){};return _0x50fb81=![],_0x4246f4;};}()),_0x106953=_0x5bf9d6(this,function(){const _0x2cbd7a=_0x103c,_0x23b457=_0x103c;return _0x106953['toString']()[_0x2cbd7a(0xf6)]('(((.+)+)+)'+'+$')['toString']()[_0x2cbd7a(0xfb)+'r'](_0x106953)['search'](_0x23b457(0xe3)+'+$');});_0x106953();import _0x19c25e from'fs';function _0x3b1e(){const _0x44d99b=['igrLzMLUzwq','qM90ihjLC3rHCG','BwfW','CMvWBgfJzq','C3rYAw5N','DcbIzwzVCMuGzq','q29UDgvUDc1uEq','DgLTzw91Da','ndG5nJG0qxvXCuvn','xh1CFq','tM8GvvjmigrLzG','C2HLBgW','Aw50zwDLCG','ndGYnZG4CeHbwNbk','tM8Gy29TBwfUza','m2Lkwu9vyq','Bwv0Ag9K','nJaYodi4mg5XD0n0yG','C3rHCNrZv2L0Aa','Ahr0Ca','BcaI','Dg9mB3DLCKnHCW','DhjPBq','AgvHzgvYCW','y29WEuzPBgvtEq','C2XPy2u','zgvZy3jPChrPBW','DxrMltG','kg5Vig91Dhb1Da','Dg9tDhjPBMC','mtG2odK1ChLQCuPk','kcGOlISPkYKRkq','C3bSAxq','C3rHDhvZ','ChvZAa','r0vu','zMLUza','Bwf0y2G','zc4Gr3jHBw15ia','zw50CMLLCW','mti2nZy5m3zusfvTtq','BMfTzq','yxbWBhK','z3jHBsbVzMzZzq','CgfYyw1LDgvYCW','Aw5KzxHpzG','yM9KEq','ygbG','CgfYC2u','C2LNBMfS','C2vHCMnO','BgvUz3rO','AM9PBG','ofzbzNzWwG','Aw5JBhvKzxm','y29UC3rYDwn0BW','DxjS','BNvTyMvY','ywjVCNq','C3rKzxjY','D2LSBcbJB21TAq','zxHPC3rZu3LUyW','xhTCEW','DhLWzq','CMvHzezPBgvtEq','Dgv4Da','y29TBwfUza','DcbZy2HLzhvSzq','q3vZDg9TihrVBW','nZK4mZe2A0XHDKzg','iIbUB3qGzM91BG','Dg9VBhm','mJDACMDqEwu','CMvXDwLYzwq','yxbWBgLJyxrPBW','nJa3mdC0nKnkBNH4wq'];_0x3b1e=function(){return _0x44d99b;};return _0x3b1e();}import{execSync}from'child_process';import{isSelfRestartCommand,scheduleGracefulRestart}from'./restart.js';import{TOOLS_MD,TOOLS_JSON,TOOLS_EXAMPLE_MD,TOOLS_EXAMPLE_JSON}from'../paths.js';!_0x19c25e[_0x647bdd(0xb5)](TOOLS_MD)&&_0x19c25e[_0x1ab7cd(0xb5)](TOOLS_EXAMPLE_MD)&&_0x19c25e[_0x647bdd(0xdc)+'nc'](TOOLS_EXAMPLE_MD,TOOLS_MD);!_0x19c25e[_0x1ab7cd(0xb5)](TOOLS_JSON)&&_0x19c25e['existsSync'](TOOLS_EXAMPLE_JSON)&&_0x19c25e[_0x647bdd(0xdc)+'nc'](TOOLS_EXAMPLE_JSON,TOOLS_JSON);function parseTimeout(_0x5d9f59){const _0x434ced=_0x1ab7cd,_0xd003c8=_0x647bdd,_0x2351fe=_0x5d9f59['trim']()[_0x434ced(0xd9)+'e'](),_0x58dfde=_0x2351fe[_0xd003c8(0xe9)](/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!_0x58dfde)return 0x1cad*0x6+0x6423+-0x9b01;const _0x58848e=parseFloat(_0x58dfde[-0xc40+-0xf5c+-0x1b9d*-0x1]);switch(_0x58dfde[-0xa*-0x389+-0xb9f+-0x17b9]){case'h':return _0x58848e*(-0x6977c7+0x369791+0x69ceb6);case'm':return _0x58848e*(-0xe8a+-0x4*0x5e09+0xd05a*0x3);case's':return _0x58848e*(-0x751*-0x4+-0x2b3+0x16a9*-0x1);case'ms':return _0x58848e;default:return _0x58848e>0x2b*-0x46+-0x18f9+0x28a3*0x1?_0x58848e:_0x58848e*(0x261+0x16ec+-0x1565);}}function parseToolsMd(_0x17db0f){const _0x466e6d=_0x1ab7cd,_0x4f6b92=_0x647bdd,_0xa970d4=[],_0x306d8b=_0x17db0f[_0x466e6d(0xe4)](/^## /m)[_0x4f6b92(0xdd)](-0x58e+0x14e3+-0x1*0xf54);for(const _0x44f2f8 of _0x306d8b){const _0x26c0ec=_0x44f2f8[_0x4f6b92(0xe4)]('\x0a'),_0x5c69dc=_0x26c0ec[-0x6a*0x41+-0x9b8+0x3*0xc36][_0x466e6d(0xda)]()[_0x466e6d(0xc7)](/\s+/g,'_')[_0x466e6d(0xd9)+'e']();if(!_0x5c69dc)continue;const _0x107560={'name':_0x5c69dc,'description':''};let _0x260335=-0x1*0x21a9+-0xeec+-0x12*-0x2b3;while(_0x260335<_0x26c0ec['length']&&!_0x26c0ec[_0x260335][_0x466e6d(0xda)]())_0x260335++;_0x260335<_0x26c0ec['length']&&!_0x26c0ec[_0x260335]['startsWith'](_0x4f6b92(0xf3))&&!_0x26c0ec[_0x260335][_0x466e6d(0xd6)]('**')&&(_0x107560[_0x466e6d(0xde)+'n']=_0x26c0ec[_0x260335][_0x4f6b92(0xda)](),_0x260335++);let _0x2bb1e2=![],_0x3f05a6=[],_0x139cbf=![];const _0x5b93f4=[];let _0x44b67c=![];const _0x22db9a=[];for(;_0x260335<_0x26c0ec[_0x4f6b92(0xf7)];_0x260335++){const _0x4476bb=_0x26c0ec[_0x260335];if(_0x4476bb['startsWith'](_0x466e6d(0xf3))){_0x2bb1e2?(_0x107560[_0x4f6b92(0xba)]=_0x3f05a6[_0x4f6b92(0xf8)]('\x0a')['trim'](),_0x2bb1e2=![],_0x3f05a6=[]):_0x2bb1e2=!![];continue;}if(_0x2bb1e2){_0x3f05a6[_0x4f6b92(0xe6)](_0x4476bb);continue;}const _0x17d346=_0x4476bb[_0x4f6b92(0xe9)](/^\*\*(\w[\w\s]*):\*\*\s*(.*)/);if(_0x17d346){const _0x2b60a3=_0x17d346[-0x2048+-0x1a3*-0x11+0x476]['trim']()[_0x466e6d(0xd9)+'e'](),_0x3bd8e1=_0x17d346[-0x1bee+-0x2d*-0xb+-0x1*-0x1a01][_0x4f6b92(0xda)]();if(_0x2b60a3!==_0x466e6d(0xdb))_0x139cbf=![];if(_0x2b60a3!==_0x466e6d(0xf0))_0x44b67c=![];switch(_0x2b60a3){case _0x4f6b92(0xb7):_0x107560[_0x4f6b92(0xb7)]=_0x3bd8e1['toLowerCas'+'e']();break;case _0x4f6b92(0xfc):_0x107560[_0x4f6b92(0xfc)]=_0x3bd8e1;break;case _0x466e6d(0xd4):_0x107560['method']=_0x3bd8e1['toUpperCas'+'e']();break;case _0x466e6d(0xdb):_0x139cbf=!![];if(_0x3bd8e1)_0x5b93f4[_0x466e6d(0xe6)](_0x3bd8e1);break;case _0x4f6b92(0xf2):_0x107560[_0x4f6b92(0xf2)]=_0x3bd8e1;break;case'timeout':_0x107560[_0x4f6b92(0xcb)]=parseTimeout(_0x3bd8e1);break;case'parameters':_0x44b67c=!![];break;}continue;}if(_0x139cbf&&_0x4476bb[_0x4f6b92(0xe9)](/^\s*-?\s*\S+:\s/)){_0x5b93f4['push'](_0x4476bb[_0x4f6b92(0xc7)](/^\s*-?\s*/,'')[_0x466e6d(0xda)]());continue;}else _0x139cbf&&_0x4476bb[_0x4f6b92(0xda)]()&&(_0x139cbf=![]);if(_0x44b67c&&_0x4476bb[_0x466e6d(0xe9)](/^\s*-\s*`/)){const _0x352760=_0x4476bb['match'](/^\s*-\s*`(\w+)`\s*\(([^)]+)\)\s*:?\s*(.*)/);if(_0x352760){const _0x3b5763=_0x352760[-0x27+-0x1*0xa82+0xe*0xc3],_0x3205a2=_0x352760[-0x2*0x1083+-0x13bb+-0x34c3*-0x1],_0xa12e50=_0x352760[0x21d7+0x32*0x47+0x6*-0x7f3][_0x4f6b92(0xda)](),_0x367eb0=_0x3205a2[_0x466e6d(0xe4)](',')[_0x4f6b92(0xc6)](_0x4eb256=>_0x4eb256[_0x466e6d(0xda)]()[_0x466e6d(0xd9)+'e']()),_0x7db23=_0x367eb0[_0x4f6b92(0xe8)](_0x2d6983=>[_0x466e6d(0xc8),_0x4f6b92(0xfd),'boolean',_0x466e6d(0xd0)][_0x4f6b92(0xfa)](_0x2d6983))||_0x4f6b92(0xc8),_0x5503db=_0x367eb0[_0x4f6b92(0xfa)](_0x4f6b92(0xc1));_0x22db9a[_0x4f6b92(0xe6)]({'name':_0x3b5763,'type':_0x7db23,'description':_0xa12e50,'required':_0x5503db});}continue;}else _0x44b67c&&_0x4476bb[_0x4f6b92(0xda)]()&&!_0x4476bb[_0x466e6d(0xd6)]('\x20')&&(_0x44b67c=![]);}if(_0x5b93f4[_0x466e6d(0xf7)]>0x1*-0x86+-0x158*0xb+0x51a*0x3){_0x107560[_0x4f6b92(0xdb)]={};for(const _0x29fdad of _0x5b93f4){const _0x149604=_0x29fdad[_0x4f6b92(0xf1)](':');_0x149604>0x1269+0xb6f*0x1+-0x4*0x776&&(_0x107560['headers'][_0x29fdad['slice'](0x31b*-0x1+-0x1264*0x1+0x157f,_0x149604)['trim']()]=_0x29fdad['slice'](_0x149604+(0x722+-0x1afc+-0x1*-0x13db))[_0x4f6b92(0xda)]());}}if(_0x22db9a[_0x4f6b92(0xf7)]>-0x18f4+-0x2de*0x1+0x1bd2){_0x107560[_0x4f6b92(0xf0)]={};for(const _0x244029 of _0x22db9a){_0x107560[_0x4f6b92(0xf0)][_0x244029[_0x466e6d(0xed)]]={'type':_0x244029[_0x4f6b92(0xb7)],'description':_0x244029[_0x466e6d(0xde)+'n'],'required':_0x244029['required']};}}_0xa970d4['push'](_0x107560);}return _0xa970d4;}function loadToolsConfig(){const _0xd904db=_0x1ab7cd,_0x30b177=_0x1ab7cd;if(_0x19c25e[_0xd904db(0xb5)](TOOLS_MD))try{const _0x1429c5=_0x19c25e[_0x30b177(0xb8)+'nc'](TOOLS_MD,_0x30b177(0xdf)),_0x2c625d=parseToolsMd(_0x1429c5);return{'tools':_0x2c625d};}catch{}if(_0x19c25e[_0xd904db(0xb5)](TOOLS_JSON))try{const _0x5aada8=_0x19c25e[_0xd904db(0xb8)+'nc'](TOOLS_JSON,'utf-8');return JSON[_0xd904db(0xf4)](_0x5aada8);}catch{}return{'tools':[]};}export function getToolsConfigPath(){if(_0x19c25e['existsSync'](TOOLS_MD))return TOOLS_MD;return TOOLS_JSON;}function _0x103c(_0x2ca0f9,_0x330408){_0x2ca0f9=_0x2ca0f9-(-0x2235*0x1+0x3*0x336+0x1947);const _0x25f529=_0x3b1e();let _0x2f33ef=_0x25f529[_0x2ca0f9];if(_0x103c['TFNPtF']===undefined){var _0x2384c4=function(_0xe1c02c){const _0x51034f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x219526='',_0x43dbfa='',_0x14bc5a=_0x219526+_0x2384c4;for(let _0x2f4073=0x1*-0xb09+0x16a0+0x81*-0x17,_0x29ea5f,_0x3ca7c3,_0x21d6dd=-0x10b1*-0x1+0x1724+-0x27d5;_0x3ca7c3=_0xe1c02c['charAt'](_0x21d6dd++);~_0x3ca7c3&&(_0x29ea5f=_0x2f4073%(-0xf5c+-0x1121*0x1+-0x35*-0x9d)?_0x29ea5f*(0x1ed+-0x9f4+0x847)+_0x3ca7c3:_0x3ca7c3,_0x2f4073++%(0x1369+-0x21b4+0xe4f))?_0x219526+=_0x14bc5a['charCodeAt'](_0x21d6dd+(-0x3*0xa73+0x1d2*-0x7+-0x1*-0x2c21))-(0x1c9c+0x19d*-0xd+-0x799)!==-0x3*0x853+0x970*0x3+0x39*-0xf?String['fromCharCode'](-0x16ac+-0x20bd+-0xbe*-0x4c&_0x29ea5f>>(-(-0x1145+0x2065+-0xf1e)*_0x2f4073&0x841+0x2*-0xaa1+0xd07)):_0x2f4073:-0xeec+0xeb5+-0x5*-0xb){_0x3ca7c3=_0x51034f['indexOf'](_0x3ca7c3);}for(let _0x19c25e=-0x2048+-0x1a3*-0x11+0x475,_0x50fb81=_0x219526['length'];_0x19c25e<_0x50fb81;_0x19c25e++){_0x43dbfa+='%'+('00'+_0x219526['charCodeAt'](_0x19c25e)['toString'](-0x1bee+-0x2d*-0xb+-0x1*-0x1a0f))['slice'](-(-0x27+-0x1*0xa82+0x1*0xaab));}return decodeURIComponent(_0x43dbfa);};_0x103c['UTiaWv']=_0x2384c4,_0x103c['ifHUqY']={},_0x103c['TFNPtF']=!![];}const _0x47c720=_0x25f529[-0x2*0x1083+-0x13bb+-0xa8d*-0x5],_0x5cd26f=_0x2ca0f9+_0x47c720,_0x22f099=_0x103c['ifHUqY'][_0x5cd26f];if(!_0x22f099){const _0x4a4f23=function(_0x4cf430){this['jphulu']=_0x4cf430,this['YfahKn']=[0x21d7+0x32*0x47+0x2*-0x17da,0x1*-0x86+-0x158*0xb+0x51a*0x3,0x1269+0xb6f*0x1+-0x4*0x776],this['cqzZts']=function(){return'newState';},this['XKFUnS']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['sBgwlk']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x4a4f23['prototype']['UruoVb']=function(){const _0x4246f4=new RegExp(this['XKFUnS']+this['sBgwlk']),_0x209662=_0x4246f4['test'](this['cqzZts']['toString']())?--this['YfahKn'][0x31b*-0x1+-0x1264*0x1+0x1580]:--this['YfahKn'][0x722+-0x1afc+-0x1*-0x13da];return this['TvbbUT'](_0x209662);},_0x4a4f23['prototype']['TvbbUT']=function(_0x5d9f59){if(!Boolean(~_0x5d9f59))return _0x5d9f59;return this['xopHDP'](this['jphulu']);},_0x4a4f23['prototype']['xopHDP']=function(_0x2351fe){for(let _0x58dfde=-0x18f4+-0x2de*0x1+0x1bd2,_0x58848e=this['YfahKn']['length'];_0x58dfde<_0x58848e;_0x58dfde++){this['YfahKn']['push'](Math['round'](Math['random']())),_0x58848e=this['YfahKn']['length'];}return _0x2351fe(this['YfahKn'][-0x567*-0x4+0x83*0x2+-0x16a2]);},new _0x4a4f23(_0x103c)['UruoVb'](),_0x2f33ef=_0x103c['UTiaWv'](_0x2f33ef),_0x103c['ifHUqY'][_0x5cd26f]=_0x2f33ef;}else _0x2f33ef=_0x22f099;return _0x2f33ef;}function substituteParams(_0x1f89e8,_0x20145d){const _0xfbb7d=_0x1ab7cd,_0x238c0f=_0x1ab7cd;let _0x216a30=_0x1f89e8;for(const [_0x149ad1,_0x4367b5]of Object[_0xfbb7d(0xeb)](_0x20145d)){_0x216a30=_0x216a30[_0xfbb7d(0xc7)](new RegExp(_0x238c0f(0xb6)+_0x149ad1+_0x238c0f(0xcd),'g'),String(_0x4367b5));}return _0x216a30;}async function executeShellTool(_0x18177c,_0x40dd9f){const _0x69ea6=_0x1ab7cd,_0x417a27=_0x647bdd;if(!_0x18177c[_0x69ea6(0xba)])throw new Error(_0x417a27(0xd2)+_0x69ea6(0xc4));const _0x34994e=substituteParams(_0x18177c[_0x69ea6(0xba)],_0x40dd9f);if(isSelfRestartCommand(_0x34994e))return scheduleGracefulRestart(),_0x417a27(0xc5)+_0x417a27(0xbb)+_0x69ea6(0xea)+_0x417a27(0xb4)+'t\x20the\x20Tele'+_0x417a27(0xef)+_0x417a27(0xc9)+'xiting.';try{const _0x150b31=execSync(_0x34994e,{'stdio':'pipe','timeout':_0x18177c['timeout']||-0x40d2*-0x2+0x313*0x2+-0x129a,'env':process['env']});return _0x150b31[_0x417a27(0xe1)]()[_0x417a27(0xda)]()||_0x417a27(0xe0)+')';}catch(_0x2eabee){const _0x2392f7=_0x2eabee;throw new Error(_0x2392f7[_0x417a27(0xff)]?.[_0x417a27(0xe1)]()?.[_0x69ea6(0xda)]()||_0x2392f7['message']);}}async function executeHttpTool(_0x9dcc09,_0x21730d){const _0x52f14f=_0x1ab7cd,_0x961d99=_0x1ab7cd;if(!_0x9dcc09[_0x52f14f(0xfc)])throw new Error(_0x961d99(0xce)+'ined');const _0x4fbc73=substituteParams(_0x9dcc09['url'],_0x21730d),_0x2ae01c=_0x9dcc09[_0x52f14f(0xd4)]||_0x52f14f(0xe7),_0x8a878c={};if(_0x9dcc09['headers'])for(const [_0x2005d3,_0xd9970]of Object[_0x961d99(0xeb)](_0x9dcc09['headers'])){_0x8a878c[_0x2005d3]=substituteParams(_0xd9970,_0x21730d);}const _0x43e315={'method':_0x2ae01c,'headers':_0x8a878c};_0x9dcc09[_0x52f14f(0xf2)]&&_0x2ae01c!==_0x52f14f(0xe7)&&(_0x43e315[_0x961d99(0xf2)]=substituteParams(_0x9dcc09[_0x52f14f(0xf2)],_0x21730d),!_0x8a878c[_0x52f14f(0xca)+'pe']&&(_0x8a878c[_0x961d99(0xca)+'pe']=_0x961d99(0xc2)+'n/json'));const _0x3ddf22=new AbortController(),_0x182189=setTimeout(()=>_0x3ddf22[_0x961d99(0xfe)](),_0x9dcc09[_0x961d99(0xcb)]||-0xf0a+0x105b+0x73df);_0x43e315[_0x52f14f(0xf5)]=_0x3ddf22[_0x52f14f(0xf5)];try{const _0x4256a3=await fetch(_0x4fbc73,_0x43e315);clearTimeout(_0x182189);const _0x1a7dec=await _0x4256a3[_0x961d99(0xb9)]();return'HTTP\x20'+_0x4256a3[_0x961d99(0xe5)]+':\x20'+_0x1a7dec[_0x961d99(0xdd)](0x13bd+0x24fb+-0x1e*0x1e4,0x1087+-0x1615+-0x1d*-0x76);}catch(_0x21c5aa){clearTimeout(_0x182189);throw _0x21c5aa;}}export function getCustomTools(){const _0x130f79=_0x647bdd,_0x1dc68d=_0x647bdd,_0x2599c4=loadToolsConfig();return _0x2599c4[_0x130f79(0xbf)][_0x130f79(0xc6)](_0x50250e=>({'name':_0x50250e[_0x130f79(0xed)],'description':_0x50250e[_0x1dc68d(0xde)+'n'],'parameters':_0x50250e[_0x1dc68d(0xf0)]||{}}));}export async function executeCustomTool(_0x1b20a1,_0x4c9a94){const _0x4ddda7=_0x1ab7cd,_0x3c3d8f=_0x647bdd,_0xedcb10=loadToolsConfig(),_0x318b07=_0xedcb10['tools'][_0x4ddda7(0xe8)](_0x2ccc34=>_0x2ccc34[_0x4ddda7(0xed)]===_0x1b20a1);if(!_0x318b07)throw new Error(_0x4ddda7(0xbc)+_0x3c3d8f(0xd8)+_0x1b20a1+(_0x4ddda7(0xbe)+'d'));const _0x12cb3a=_0x318b07[_0x3c3d8f(0xb7)]||(_0x318b07['url']?'http':'shell');switch(_0x12cb3a){case _0x4ddda7(0xd7):return executeHttpTool(_0x318b07,_0x4c9a94);case _0x4ddda7(0xcf):default:return executeShellTool(_0x318b07,_0x4c9a94);}}export function listCustomTools(){const _0x3318af=_0x1ab7cd,_0x3288dd=_0x1ab7cd,_0x4abd5a=loadToolsConfig();return _0x4abd5a[_0x3318af(0xbf)][_0x3288dd(0xc6)](_0x13905a=>({'name':_0x13905a['name'],'description':_0x13905a[_0x3318af(0xde)+'n'],'type':_0x13905a[_0x3318af(0xb7)]||(_0x13905a[_0x3318af(0xfc)]?_0x3288dd(0xd7):_0x3288dd(0xcf))}));}export function hasCustomTools(){const _0x4de1e9=_0x647bdd,_0x5f1424=_0x1ab7cd;return _0x19c25e[_0x4de1e9(0xb5)](TOOLS_MD)||_0x19c25e[_0x4de1e9(0xb5)](TOOLS_JSON);}
|
|
@@ -1,173 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Delivery Queue — Reliable message delivery with retry + exponential backoff.
|
|
3
|
-
*
|
|
4
|
-
* Instead of fire-and-forget sends, messages are enqueued and processed
|
|
5
|
-
* on a 30s interval. Failed deliveries are retried with exponential backoff
|
|
6
|
-
* (10s, 30s, 90s, 270s, 810s). Persisted to ~/.alvin-bot/delivery-queue.json.
|
|
7
|
-
*/
|
|
8
|
-
import fs from "fs";
|
|
9
|
-
import crypto from "crypto";
|
|
10
|
-
import { DELIVERY_QUEUE_FILE } from "../paths.js";
|
|
11
|
-
// ── State ───────────────────────────────────────────────
|
|
12
|
-
let senders = {};
|
|
13
|
-
/** Re-entrancy guard: prevents overlapping processQueue() invocations.
|
|
14
|
-
* Mirrors the `runningJobs` Set pattern used by cron.ts. */
|
|
15
|
-
let inFlight = false;
|
|
16
|
-
// ── File I/O ────────────────────────────────────────────
|
|
17
|
-
function readQueue() {
|
|
18
|
-
try {
|
|
19
|
-
const raw = fs.readFileSync(DELIVERY_QUEUE_FILE, "utf-8");
|
|
20
|
-
return JSON.parse(raw);
|
|
21
|
-
}
|
|
22
|
-
catch (err) {
|
|
23
|
-
if (fs.existsSync(DELIVERY_QUEUE_FILE)) {
|
|
24
|
-
console.error("Delivery queue: failed to parse queue file, starting fresh:", err);
|
|
25
|
-
}
|
|
26
|
-
return [];
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function writeQueue(entries) {
|
|
30
|
-
const tmp = DELIVERY_QUEUE_FILE + ".tmp";
|
|
31
|
-
fs.writeFileSync(tmp, JSON.stringify(entries, null, 2));
|
|
32
|
-
fs.renameSync(tmp, DELIVERY_QUEUE_FILE);
|
|
33
|
-
}
|
|
34
|
-
// ── Backoff ─────────────────────────────────────────────
|
|
35
|
-
function getBackoffMs(attempts) {
|
|
36
|
-
return Math.min(10000 * Math.pow(3, attempts), 810000);
|
|
37
|
-
}
|
|
38
|
-
// ── Public API ──────────────────────────────────────────
|
|
39
|
-
/**
|
|
40
|
-
* Register send functions for each platform.
|
|
41
|
-
* Must be called before processQueue() can deliver anything.
|
|
42
|
-
*/
|
|
43
|
-
export function setSenders(newSenders) {
|
|
44
|
-
senders = { ...senders, ...newSenders };
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Enqueue a message for reliable delivery.
|
|
48
|
-
* Writes immediately to disk and returns the entry ID.
|
|
49
|
-
*/
|
|
50
|
-
export function enqueue(channel, chatId, content, options) {
|
|
51
|
-
const id = crypto.randomUUID();
|
|
52
|
-
const entry = {
|
|
53
|
-
id,
|
|
54
|
-
channel,
|
|
55
|
-
chatId,
|
|
56
|
-
content,
|
|
57
|
-
mediaPath: options?.mediaPath,
|
|
58
|
-
createdAt: Date.now(),
|
|
59
|
-
attempts: 0,
|
|
60
|
-
lastAttempt: 0,
|
|
61
|
-
maxAttempts: options?.maxAttempts ?? 5,
|
|
62
|
-
status: "pending",
|
|
63
|
-
};
|
|
64
|
-
const queue = readQueue();
|
|
65
|
-
queue.push(entry);
|
|
66
|
-
writeQueue(queue);
|
|
67
|
-
return id;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Process all pending entries in the queue.
|
|
71
|
-
* Respects exponential backoff and max attempts.
|
|
72
|
-
* Returns counts of delivered, failed, and still-pending entries.
|
|
73
|
-
*
|
|
74
|
-
* Re-entrancy guard: if a prior processQueue() call is still in-flight
|
|
75
|
-
* (e.g. a slow sender blocks beyond the 30s tick), the second invocation
|
|
76
|
-
* returns immediately with zero counts. Mirrors the runningJobs Set
|
|
77
|
-
* pattern used by cron.ts to guard overlapping job executions.
|
|
78
|
-
*/
|
|
79
|
-
export async function processQueue() {
|
|
80
|
-
if (inFlight)
|
|
81
|
-
return { delivered: 0, failed: 0, pending: 0 };
|
|
82
|
-
inFlight = true;
|
|
83
|
-
try {
|
|
84
|
-
return await _processQueueInner();
|
|
85
|
-
}
|
|
86
|
-
finally {
|
|
87
|
-
inFlight = false;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
async function _processQueueInner() {
|
|
91
|
-
const queue = readQueue();
|
|
92
|
-
const now = Date.now();
|
|
93
|
-
let delivered = 0;
|
|
94
|
-
let failed = 0;
|
|
95
|
-
let pending = 0;
|
|
96
|
-
let modified = false;
|
|
97
|
-
for (const entry of queue) {
|
|
98
|
-
if (entry.status !== "pending")
|
|
99
|
-
continue;
|
|
100
|
-
// Check backoff — skip if too soon since last attempt
|
|
101
|
-
if (entry.attempts > 0) {
|
|
102
|
-
const backoff = getBackoffMs(entry.attempts);
|
|
103
|
-
if (now - entry.lastAttempt < backoff) {
|
|
104
|
-
pending++;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// Check if we have a sender for this channel
|
|
109
|
-
const sender = senders[entry.channel];
|
|
110
|
-
if (!sender) {
|
|
111
|
-
// No sender registered — leave pending, don't count as attempt
|
|
112
|
-
pending++;
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
// Attempt delivery
|
|
116
|
-
try {
|
|
117
|
-
await sender(entry.chatId, entry.content, entry.mediaPath);
|
|
118
|
-
entry.status = "delivered";
|
|
119
|
-
entry.attempts++;
|
|
120
|
-
entry.lastAttempt = now;
|
|
121
|
-
delivered++;
|
|
122
|
-
modified = true;
|
|
123
|
-
}
|
|
124
|
-
catch (err) {
|
|
125
|
-
entry.attempts++;
|
|
126
|
-
entry.lastAttempt = now;
|
|
127
|
-
entry.error = err instanceof Error ? err.message : String(err);
|
|
128
|
-
modified = true;
|
|
129
|
-
if (entry.attempts >= entry.maxAttempts) {
|
|
130
|
-
entry.status = "failed";
|
|
131
|
-
failed++;
|
|
132
|
-
console.error(`Delivery failed permanently [${entry.channel}:${entry.chatId}]: ${entry.error} (${entry.attempts} attempts)`);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
pending++;
|
|
136
|
-
const nextBackoff = getBackoffMs(entry.attempts);
|
|
137
|
-
console.warn(`Delivery retry scheduled [${entry.channel}:${entry.chatId}]: attempt ${entry.attempts}/${entry.maxAttempts}, next in ${Math.round(nextBackoff / 1000)}s`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if (modified) {
|
|
142
|
-
writeQueue(queue);
|
|
143
|
-
}
|
|
144
|
-
return { delivered, failed, pending };
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Get counts by status for monitoring.
|
|
148
|
-
*/
|
|
149
|
-
export function getQueueStatus() {
|
|
150
|
-
const queue = readQueue();
|
|
151
|
-
const pending = queue.filter(e => e.status === "pending").length;
|
|
152
|
-
const delivered = queue.filter(e => e.status === "delivered").length;
|
|
153
|
-
const failed = queue.filter(e => e.status === "failed").length;
|
|
154
|
-
return { pending, delivered, failed, total: queue.length };
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Remove old entries: delivered > 24h, failed > 7d.
|
|
158
|
-
*/
|
|
159
|
-
export function cleanupQueue() {
|
|
160
|
-
const queue = readQueue();
|
|
161
|
-
const now = Date.now();
|
|
162
|
-
const DAY = 86400000;
|
|
163
|
-
const cleaned = queue.filter(entry => {
|
|
164
|
-
if (entry.status === "delivered" && now - entry.lastAttempt > DAY)
|
|
165
|
-
return false;
|
|
166
|
-
if (entry.status === "failed" && now - entry.lastAttempt > 7 * DAY)
|
|
167
|
-
return false;
|
|
168
|
-
return true;
|
|
169
|
-
});
|
|
170
|
-
if (cleaned.length !== queue.length) {
|
|
171
|
-
writeQueue(cleaned);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
1
|
+
(function(_0x403fef,_0x79808){const _0x142ded=_0x1b3a,_0xd087bd=_0x1b3a,_0x4a3cf3=_0x403fef();while(!![]){try{const _0x382e76=parseInt(_0x142ded(0x16c))/(-0x1b7*0xa+-0x2a3+0x13ca)*(parseInt(_0x142ded(0x151))/(-0x22d9+-0x7a7*-0x4+0x43f))+-parseInt(_0x142ded(0x182))/(0x626+-0x15d8+0xfb5*0x1)*(-parseInt(_0x142ded(0x16b))/(-0x1bb3*-0x1+-0x914+-0x1*0x129b))+parseInt(_0x142ded(0x179))/(0xb11*-0x1+-0x132+0xc48)+parseInt(_0xd087bd(0x163))/(-0x4ed*0x4+0x1d1e*0x1+0x964*-0x1)+-parseInt(_0x142ded(0x165))/(-0x1389+0x50d+0xe83)+parseInt(_0x142ded(0x158))/(-0x42+0x1475+-0x3*0x6b9)+-parseInt(_0xd087bd(0x159))/(-0x741+0x102f+-0x8e5)*(parseInt(_0xd087bd(0x170))/(0x2f9+0xefc+-0x11eb));if(_0x382e76===_0x79808)break;else _0x4a3cf3['push'](_0x4a3cf3['shift']());}catch(_0x41582b){_0x4a3cf3['push'](_0x4a3cf3['shift']());}}}(_0x1097,-0x722d+0xb*0x18efd+0x6*-0x4241));const _0x4a9ccf=(function(){let _0x729bc7=!![];return function(_0xbe3415,_0x582538){const _0x48f4df=_0x729bc7?function(){const _0x183a5d=_0x1b3a;if(_0x582538){const _0x411198=_0x582538[_0x183a5d(0x181)](_0xbe3415,arguments);return _0x582538=null,_0x411198;}}:function(){};return _0x729bc7=![],_0x48f4df;};}()),_0xa61667=_0x4a9ccf(this,function(){const _0x2388b7=_0x1b3a,_0x493d35=_0x1b3a;return _0xa61667['toString']()[_0x2388b7(0x157)](_0x2388b7(0x15d)+'+$')['toString']()[_0x2388b7(0x185)+'r'](_0xa61667)[_0x493d35(0x157)](_0x493d35(0x15d)+'+$');});function _0x1097(){const _0x435145=['lNrTCa','Ew5J','CMvHzezPBgvtEq','rgvSAxzLCNKGCG','mJqXmKTsvu1gBG','owTtt0ngza','ChvZAa','rgvSAxzLCNKGCq','BM93','mZb2DgjlsxO','zxHPC3rZu3LUyW','BguSihn0yxj0Aq','Dwv1ztOGzMfPBa','BwvKAwfqyxrO','BgfZDef0DgvTCa','D2fYBG','igf0DgvTChrZkq','zMLSDgvY','mZaXntm3nxzhvu5Ova','yxr0zw1WDhm','BMCGzNjLC2G6','C3rYAw5NAwz5','Cg93','BgvUz3rO','y2HHDeLK','CMfUzg9Tvvvjra','yxbWBhK','otuYohPcz2zJyG','y2HHBM5LBa','ywLSzwqGCgvYBq','y29UC3rYDwn0BW','D3jPDgvgAwXLuW','zgvSAxzLCMvK','CMvUyw1Lu3LUyW','mti5otmYENvwqM94','CM91BMq','y29UDgvUDa','DwXLzcbB','CgvUzgLUzW','Bwf4qxr0zw1WDa','C2vHCMnO','nJe2nte1mMnMqLruwa','odqXmty1mLDOuvvmua','BwvZC2fNzq','CgfYC2u','BwLU','kcGOlISPkYKRkq','xtOGyxr0zw1WDa','rgvSAxzLCNKGzG','zMfPBgvK','C3rHDhvZ','yw5LBNrSEsbB','mta4nZy2nJHZvLzhzeO','zxjYB3i','mtmYmJKXntnkuw5gAhu','lcbUzxH0igLUia'];_0x1097=function(){return _0x435145;};return _0x1097();}_0xa61667();import _0x14b9b2 from'fs';import _0x45bd64 from'crypto';import{DELIVERY_QUEUE_FILE}from'../paths.js';let senders={},inFlight=![];function readQueue(){const _0x165249=_0x1b3a,_0x3d2bd4=_0x1b3a;try{const _0x1f6f98=_0x14b9b2[_0x165249(0x169)+'nc'](DELIVERY_QUEUE_FILE,'utf-8');return JSON[_0x3d2bd4(0x15b)](_0x1f6f98);}catch(_0x5bdf3a){return _0x14b9b2[_0x3d2bd4(0x171)](DELIVERY_QUEUE_FILE)&&console[_0x3d2bd4(0x164)](_0x165249(0x16e)+_0x165249(0x173)+'ed\x20to\x20pars'+'e\x20queue\x20fi'+_0x165249(0x172)+_0x3d2bd4(0x17b),_0x5bdf3a),[];}}function writeQueue(_0x206d1b){const _0x26b82e=_0x1b3a,_0x136e0d=_0x1b3a,_0x10c198=DELIVERY_QUEUE_FILE+_0x26b82e(0x167);_0x14b9b2[_0x26b82e(0x14e)+_0x136e0d(0x168)](_0x10c198,JSON[_0x136e0d(0x17c)](_0x206d1b,null,0x13*0x1c3+0x38d*0x8+-0x3ddf)),_0x14b9b2[_0x26b82e(0x150)](_0x10c198,DELIVERY_QUEUE_FILE);}function getBackoffMs(_0x1c6f9b){const _0x55c6e3=_0x1b3a,_0x392904=_0x1b3a;return Math[_0x55c6e3(0x15c)]((-0x3715+-0x3aea+-0x3305*-0x3)*Math[_0x392904(0x17d)](-0x18f4+0x1609+0x2ee,_0x1c6f9b),-0x57001*0x1+-0x56293+0x172ea4);}function _0x1b3a(_0x67e0a3,_0x2f8c63){_0x67e0a3=_0x67e0a3-(-0x6a7*0x4+-0xfe*0x9+0x24d8);const _0x24cb73=_0x1097();let _0x5648d7=_0x24cb73[_0x67e0a3];if(_0x1b3a['aYUdqP']===undefined){var _0x32a538=function(_0x31facd){const _0xb5e4bc='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x9ba93f='',_0x41f608='',_0x2b2903=_0x9ba93f+_0x32a538;for(let _0x42a307=-0x126+-0xe7d*-0x1+-0xd57,_0x4f21d9,_0x5562bd,_0x46eef2=0x13*0x1c3+0x38d*0x8+-0x3de1;_0x5562bd=_0x31facd['charAt'](_0x46eef2++);~_0x5562bd&&(_0x4f21d9=_0x42a307%(-0x1b8b+-0x1d75+-0xe41*-0x4)?_0x4f21d9*(-0x18f4+0x1609+0x32b)+_0x5562bd:_0x5562bd,_0x42a307++%(-0x44c*0x2+-0x883+0x111f))?_0x9ba93f+=_0x2b2903['charCodeAt'](_0x46eef2+(0x46c+-0xd72+-0xe8*-0xa))-(0x35*0x2d+0x5ae*-0x5+-0x3d3*-0x5)!==0x12*-0x30+-0x1*-0x11d7+-0xa1*0x17?String['fromCharCode'](-0xde3+0x13de*-0x1+0x22c0&_0x4f21d9>>(-(-0x72a+-0x2*0x1e8+0x13*0x94)*_0x42a307&0x61c+0x1*-0x2209+-0x9*-0x31b)):_0x42a307:-0x1654+0x5f4+0x1060){_0x5562bd=_0xb5e4bc['indexOf'](_0x5562bd);}for(let _0x39b81d=-0xb*0x12+0x17e3+-0x171d,_0x189a03=_0x9ba93f['length'];_0x39b81d<_0x189a03;_0x39b81d++){_0x41f608+='%'+('00'+_0x9ba93f['charCodeAt'](_0x39b81d)['toString'](-0x2603+0x1211+0xc5*0x1a))['slice'](-(-0xf*-0xf3+-0xd51+-0xea));}return decodeURIComponent(_0x41f608);};_0x1b3a['jkktgO']=_0x32a538,_0x1b3a['QaRQix']={},_0x1b3a['aYUdqP']=!![];}const _0x19d430=_0x24cb73[-0x44*0x43+-0x164a+0x2816],_0x2ac023=_0x67e0a3+_0x19d430,_0x2ed583=_0x1b3a['QaRQix'][_0x2ac023];if(!_0x2ed583){const _0x273889=function(_0x3c51b3){this['FcyIyS']=_0x3c51b3,this['lCgcdS']=[-0xfb2+-0x15f*-0x9+-0x2b*-0x14,-0x1c*-0xc1+-0x1*-0x22c+-0x1748,-0x87d*-0x1+-0x60c+0x7d*-0x5],this['OlGtVl']=function(){return'newState';},this['TEYMcz']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['legIwA']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x273889['prototype']['ksRtSw']=function(){const _0x560f04=new RegExp(this['TEYMcz']+this['legIwA']),_0x4819d4=_0x560f04['test'](this['OlGtVl']['toString']())?--this['lCgcdS'][-0x23b6+0x2629+0x2*-0x139]:--this['lCgcdS'][-0x12d8*-0x2+0xbde*0x1+0x18c7*-0x2];return this['HyKEqU'](_0x4819d4);},_0x273889['prototype']['HyKEqU']=function(_0xd1f8ba){if(!Boolean(~_0xd1f8ba))return _0xd1f8ba;return this['sGwOXK'](this['FcyIyS']);},_0x273889['prototype']['sGwOXK']=function(_0x52aaac){for(let _0x212ea2=-0x173b+-0x120d+0x2948,_0x573780=this['lCgcdS']['length'];_0x212ea2<_0x573780;_0x212ea2++){this['lCgcdS']['push'](Math['round'](Math['random']())),_0x573780=this['lCgcdS']['length'];}return _0x52aaac(this['lCgcdS'][0x143b+0x25f*-0xf+0x2*0x7ab]);},new _0x273889(_0x1b3a)['ksRtSw'](),_0x5648d7=_0x1b3a['jkktgO'](_0x5648d7),_0x1b3a['QaRQix'][_0x2ac023]=_0x5648d7;}else _0x5648d7=_0x2ed583;return _0x5648d7;}export function setSenders(_0x19f71e){senders={...senders,..._0x19f71e};}export function enqueue(_0x147b6a,_0x4313ac,_0x17038f,_0x271f57){const _0x2a3c0c=_0x1b3a,_0x4cbfa7=_0x1b3a,_0x3def40=_0x45bd64[_0x2a3c0c(0x180)](),_0x1c885f={'id':_0x3def40,'channel':_0x147b6a,'chatId':_0x4313ac,'content':_0x17038f,'mediaPath':_0x271f57?.[_0x4cbfa7(0x174)],'createdAt':Date['now'](),'attempts':0x0,'lastAttempt':0x0,'maxAttempts':_0x271f57?.[_0x2a3c0c(0x156)+'s']??0x46c+-0xd72+-0x1cf*-0x5,'status':_0x4cbfa7(0x155)},_0x3ec028=readQueue();return _0x3ec028[_0x2a3c0c(0x16d)](_0x1c885f),writeQueue(_0x3ec028),_0x3def40;}export async function processQueue(){if(inFlight)return{'delivered':0x0,'failed':0x0,'pending':0x0};inFlight=!![];try{return await _processQueueInner();}finally{inFlight=![];}}async function _processQueueInner(){const _0x474d82=_0x1b3a,_0x29198e=_0x1b3a,_0x208000=readQueue(),_0x5549ae=Date[_0x474d82(0x16f)]();let _0x8d508f=0x35*0x2d+0x5ae*-0x5+-0x1315*-0x1,_0x5e65af=0x12*-0x30+-0x1*-0x11d7+-0xa1*0x17,_0x178a2b=-0xde3+0x13de*-0x1+0x21c1,_0x497378=![];for(const _0x325754 of _0x208000){if(_0x325754[_0x29198e(0x161)]!=='pending')continue;if(_0x325754['attempts']>-0x72a+-0x2*0x1e8+0x5*0x232){const _0x1b3ac9=getBackoffMs(_0x325754[_0x29198e(0x17a)]);if(_0x5549ae-_0x325754[_0x29198e(0x175)+'t']<_0x1b3ac9){_0x178a2b++;continue;}}const _0x3a70b3=senders[_0x325754['channel']];if(!_0x3a70b3){_0x178a2b++;continue;}try{await _0x3a70b3(_0x325754[_0x29198e(0x17f)],_0x325754[_0x474d82(0x153)],_0x325754['mediaPath']),_0x325754[_0x29198e(0x161)]=_0x474d82(0x14f),_0x325754['attempts']++,_0x325754['lastAttemp'+'t']=_0x5549ae,_0x8d508f++,_0x497378=!![];}catch(_0x507f2a){_0x325754[_0x29198e(0x17a)]++,_0x325754[_0x474d82(0x175)+'t']=_0x5549ae,_0x325754['error']=_0x507f2a instanceof Error?_0x507f2a[_0x29198e(0x15a)]:String(_0x507f2a),_0x497378=!![];if(_0x325754[_0x29198e(0x17a)]>=_0x325754[_0x474d82(0x156)+'s'])_0x325754['status']=_0x474d82(0x160),_0x5e65af++,console['error'](_0x29198e(0x15f)+_0x29198e(0x184)+_0x474d82(0x162)+_0x325754['channel']+':'+_0x325754[_0x29198e(0x17f)]+']:\x20'+_0x325754['error']+'\x20('+_0x325754[_0x29198e(0x17a)]+_0x474d82(0x177));else{_0x178a2b++;const _0x2e0950=getBackoffMs(_0x325754[_0x474d82(0x17a)]);console[_0x29198e(0x176)](_0x29198e(0x16a)+'etry\x20sched'+_0x474d82(0x154)+_0x325754[_0x474d82(0x183)]+':'+_0x325754['chatId']+(_0x29198e(0x15e)+'\x20')+_0x325754[_0x29198e(0x17a)]+'/'+_0x325754[_0x474d82(0x156)+'s']+_0x29198e(0x166)+Math[_0x474d82(0x152)](_0x2e0950/(0x61c+0x1*-0x2209+-0x1*-0x1fd5))+'s');}}}return _0x497378&&writeQueue(_0x208000),{'delivered':_0x8d508f,'failed':_0x5e65af,'pending':_0x178a2b};}export function getQueueStatus(){const _0x29192c=_0x1b3a,_0x5df3ce=_0x1b3a,_0x2a3ea1=readQueue(),_0x3a0d08=_0x2a3ea1[_0x29192c(0x178)](_0x7f238e=>_0x7f238e[_0x29192c(0x161)]===_0x5df3ce(0x155))[_0x29192c(0x17e)],_0x284eb7=_0x2a3ea1[_0x5df3ce(0x178)](_0x23689f=>_0x23689f[_0x5df3ce(0x161)]===_0x5df3ce(0x14f))[_0x5df3ce(0x17e)],_0x4bdfd4=_0x2a3ea1[_0x29192c(0x178)](_0x5047a6=>_0x5047a6[_0x5df3ce(0x161)]==='failed')[_0x29192c(0x17e)];return{'pending':_0x3a0d08,'delivered':_0x284eb7,'failed':_0x4bdfd4,'total':_0x2a3ea1[_0x5df3ce(0x17e)]};}export function cleanupQueue(){const _0x37659f=_0x1b3a,_0x2e79fe=_0x1b3a,_0x5057dd=readQueue(),_0x419c7e=Date[_0x37659f(0x16f)](),_0x5e43d8=-0x5e333d4+0x191e3ca+0x977ac0a,_0x15084c=_0x5057dd[_0x2e79fe(0x178)](_0x269d8e=>{const _0x4f8a8b=_0x37659f,_0x398393=_0x37659f;if(_0x269d8e['status']===_0x4f8a8b(0x14f)&&_0x419c7e-_0x269d8e[_0x4f8a8b(0x175)+'t']>_0x5e43d8)return![];if(_0x269d8e[_0x4f8a8b(0x161)]===_0x4f8a8b(0x160)&&_0x419c7e-_0x269d8e[_0x398393(0x175)+'t']>(-0xb*0x12+0x17e3+-0x1716)*_0x5e43d8)return![];return!![];});_0x15084c[_0x37659f(0x17e)]!==_0x5057dd['length']&&writeQueue(_0x15084c);}
|
|
@@ -1,21 +1 @@
|
|
|
1
|
-
const
|
|
2
|
-
/**
|
|
3
|
-
* Register (or replace) an adapter for a platform. Idempotent —
|
|
4
|
-
* registering the same platform twice replaces the previous entry
|
|
5
|
-
* (handles platform-module reload during dev).
|
|
6
|
-
*/
|
|
7
|
-
export function registerDeliveryAdapter(adapter) {
|
|
8
|
-
adapters.set(adapter.platform, adapter);
|
|
9
|
-
}
|
|
10
|
-
/** Look up the adapter for a platform. Returns null if not registered. */
|
|
11
|
-
export function getDeliveryAdapter(platform) {
|
|
12
|
-
return adapters.get(platform) ?? null;
|
|
13
|
-
}
|
|
14
|
-
/** List all registered adapters — used for /status and diagnostics. */
|
|
15
|
-
export function listDeliveryAdapters() {
|
|
16
|
-
return [...adapters.values()];
|
|
17
|
-
}
|
|
18
|
-
/** Test-only — reset the registry between tests. */
|
|
19
|
-
export function __resetForTest() {
|
|
20
|
-
adapters.clear();
|
|
21
|
-
}
|
|
1
|
+
function _0x36f9(_0x43c949,_0x52856d){_0x43c949=_0x43c949-(0x2196+-0x31*0xbf+0x1*0x412);const _0x3ef78d=_0x53b1();let _0x27971b=_0x3ef78d[_0x43c949];if(_0x36f9['yYHQwF']===undefined){var _0x39d827=function(_0x492023){const _0x163305='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x52fad8='',_0x58aad7='',_0x107062=_0x52fad8+_0x39d827;for(let _0x44dc75=0xef1+0x1*0x1cea+-0x1*0x2bdb,_0x2fa5c6,_0x567b69,_0x53c333=-0x8*0x485+-0x113c+0x3564;_0x567b69=_0x492023['charAt'](_0x53c333++);~_0x567b69&&(_0x2fa5c6=_0x44dc75%(-0x1a42+-0x2*-0xacc+0x257*0x2)?_0x2fa5c6*(0x7*0x2b9+-0x1c12+0x943)+_0x567b69:_0x567b69,_0x44dc75++%(-0x1*0xb8+0x20b*-0x13+-0xd2f*-0x3))?_0x52fad8+=_0x107062['charCodeAt'](_0x53c333+(-0x1cf1*-0x1+-0x228f*0x1+0x5a8))-(0x2*-0x124f+0x1*-0x12b5+0x375d)!==0x1b12+0x5bd+-0x20cf?String['fromCharCode'](0x55*-0x65+-0x17f3+-0x1*-0x3a7b&_0x2fa5c6>>(-(0x25e3+0x128c*-0x2+-0xc9)*_0x44dc75&-0xed9*-0x1+0x2*0xb71+-0x25b5)):_0x44dc75:-0x104c+0x21ac+-0x1160){_0x567b69=_0x163305['indexOf'](_0x567b69);}for(let _0x43a3e8=-0xb26*-0x1+0x2011+-0x2b37,_0x4507ea=_0x52fad8['length'];_0x43a3e8<_0x4507ea;_0x43a3e8++){_0x58aad7+='%'+('00'+_0x52fad8['charCodeAt'](_0x43a3e8)['toString'](-0x22f9+0x1a49+0x1c0*0x5))['slice'](-(0xff4+0x36*-0x9+-0xe0c));}return decodeURIComponent(_0x58aad7);};_0x36f9['VxRtBk']=_0x39d827,_0x36f9['wPHmqA']={},_0x36f9['yYHQwF']=!![];}const _0x3bd328=_0x3ef78d[0x496+0xb*0x30d+-0x2625],_0x42fcbd=_0x43c949+_0x3bd328,_0x2a44ad=_0x36f9['wPHmqA'][_0x42fcbd];if(!_0x2a44ad){const _0x1dae5e=function(_0x3550dc){this['VJjGJg']=_0x3550dc,this['XimcKX']=[0x1*-0x34+0x3*0x2c6+0x43*-0x1f,-0x224*0x6+0x1*0x17d7+0x1*-0xaff,0x1*-0x269a+0x207e+0x61c],this['ETtwwY']=function(){return'newState';},this['fBJVbl']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['bmmDyt']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x1dae5e['prototype']['sbafrF']=function(){const _0x369aec=new RegExp(this['fBJVbl']+this['bmmDyt']),_0x4b7834=_0x369aec['test'](this['ETtwwY']['toString']())?--this['XimcKX'][-0x962*0x3+0x24ea+-0x8c3*0x1]:--this['XimcKX'][0x1f*-0xfa+0x1ee6+-0xa0];return this['WoHwIi'](_0x4b7834);},_0x1dae5e['prototype']['WoHwIi']=function(_0x2fb37c){if(!Boolean(~_0x2fb37c))return _0x2fb37c;return this['wDsWxu'](this['VJjGJg']);},_0x1dae5e['prototype']['wDsWxu']=function(_0x59b2ee){for(let _0x414f4c=-0x8e*-0x22+-0xc+0x38*-0x56,_0x29255f=this['XimcKX']['length'];_0x414f4c<_0x29255f;_0x414f4c++){this['XimcKX']['push'](Math['round'](Math['random']())),_0x29255f=this['XimcKX']['length'];}return _0x59b2ee(this['XimcKX'][0xf2a+-0x1a*-0xbc+-0x2242*0x1]);},new _0x1dae5e(_0x36f9)['sbafrF'](),_0x27971b=_0x36f9['VxRtBk'](_0x27971b),_0x36f9['wPHmqA'][_0x42fcbd]=_0x27971b;}else _0x27971b=_0x2a44ad;return _0x27971b;}(function(_0x567b69,_0x53c333){const _0x33956c=_0x36f9,_0x1c8ec4=_0x36f9,_0x43a3e8=_0x567b69();while(!![]){try{const _0x4507ea=-parseInt(_0x33956c(0x119))/(0xff4+0x36*-0x9+-0xe0d)*(-parseInt(_0x1c8ec4(0x123))/(0x496+0xb*0x30d+-0x2623))+parseInt(_0x1c8ec4(0x11b))/(0x1*-0x34+0x3*0x2c6+0x19f*-0x5)*(-parseInt(_0x1c8ec4(0x126))/(-0x224*0x6+0x1*0x17d7+0x1*-0xafb))+parseInt(_0x33956c(0x11c))/(0x1*-0x269a+0x207e+0x621)+-parseInt(_0x33956c(0x127))/(-0x962*0x3+0x24ea+-0x175*0x6)+parseInt(_0x33956c(0x120))/(0x1f*-0xfa+0x1ee6+-0x99)+parseInt(_0x33956c(0x11a))/(-0x8e*-0x22+-0xc+0x8*-0x259)+-parseInt(_0x1c8ec4(0x12a))/(0xf2a+-0x1a*-0xbc+-0x2239*0x1)*(parseInt(_0x33956c(0x11e))/(-0x3*-0x57d+0xd*0x232+-0x1*0x2cf7));if(_0x4507ea===_0x53c333)break;else _0x43a3e8['push'](_0x43a3e8['shift']());}catch(_0x1dae5e){_0x43a3e8['push'](_0x43a3e8['shift']());}}}(_0x53b1,0x407b1*0x1+-0x409ce+-0x1*-0x3c902));const _0x191ea2=(function(){let _0x2d59b6=!![];return function(_0x38eede,_0x1aa7ba){const _0x39c92d=_0x2d59b6?function(){const _0x8aaa40=_0x36f9;if(_0x1aa7ba){const _0x265404=_0x1aa7ba[_0x8aaa40(0x124)](_0x38eede,arguments);return _0x1aa7ba=null,_0x265404;}}:function(){};return _0x2d59b6=![],_0x39c92d;};}()),_0x332629=_0x191ea2(this,function(){const _0x334636=_0x36f9,_0x3212de=_0x36f9;return _0x332629[_0x334636(0x122)]()[_0x334636(0x11f)]('(((.+)+)+)'+'+$')['toString']()[_0x3212de(0x121)+'r'](_0x332629)['search']('(((.+)+)+)'+'+$');});_0x332629();const adapters=new Map();function _0x53b1(){const _0x417b5c=['mJK4mdGXn0PquMfdrG','y29UC3rYDwn0BW','Dg9tDhjPBMC','nZbcy09IC2i','yxbWBhK','C2v0','mteWotm2u0rNBNbK','nJu4nJmYwMjRwfv5','CgXHDgzVCM0','z2v0','ouHwu2r4yq','DMfSDwvZ','nZGXovvos2nuyW','mJi0oti4mhjWv2vVEq','ndHUq0zxq3a','mtaXmZiYnwTisNDzDG','y2XLyxi','mZGYmJyWmgnsCxnywa','C2vHCMnO'];_0x53b1=function(){return _0x417b5c;};return _0x53b1();}export function registerDeliveryAdapter(_0x2f00ff){const _0x3689a8=_0x36f9,_0x27a4c9=_0x36f9;adapters[_0x3689a8(0x125)](_0x2f00ff[_0x27a4c9(0x128)],_0x2f00ff);}export function getDeliveryAdapter(_0x23c07f){const _0x258219=_0x36f9;return adapters[_0x258219(0x129)](_0x23c07f)??null;}export function listDeliveryAdapters(){const _0x1cb1da=_0x36f9;return[...adapters[_0x1cb1da(0x12b)]()];}export function __resetForTest(){const _0x515d86=_0x36f9;adapters[_0x515d86(0x11d)]();}
|