alvin-bot 5.7.0 → 5.8.1
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 +25 -0
- package/README.md +25 -31
- 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 -174
- 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 -583
- 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 -86
- 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 -1902
- 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 _0x15f4bf=_0x24ac,_0x1dcb10=_0x24ac;(function(_0x1829be,_0x3f4fe4){const _0x533810=_0x24ac,_0x354585=_0x24ac,_0x52223e=_0x1829be();while(!![]){try{const _0x483cd6=-parseInt(_0x533810(0xd6))/(-0x25e0+0x137*-0x5+0x3a*0xc2)*(parseInt(_0x533810(0xc9))/(-0xb40+0x90b+-0x1*-0x237))+-parseInt(_0x533810(0xd7))/(-0x1ad7+0x67*-0x1a+0x2550)+parseInt(_0x354585(0xee))/(-0x2*-0xe6e+0x235b*0x1+-0x5f*0xad)*(-parseInt(_0x354585(0x101))/(-0xdc2*0x2+-0x183*0xf+0x2*0x191b))+-parseInt(_0x533810(0xed))/(0xd44+-0xff7*0x1+0x2b9*0x1)+-parseInt(_0x533810(0xe2))/(-0x17a2+0x2027+-0x87e)*(-parseInt(_0x533810(0xd3))/(-0xedc*-0x2+-0xd31+0x29*-0x67))+-parseInt(_0x533810(0x10a))/(0x372+-0x231e+0x1fb5)+parseInt(_0x354585(0xe5))/(0x155d+-0x1efc+0x9a9);if(_0x483cd6===_0x3f4fe4)break;else _0x52223e['push'](_0x52223e['shift']());}catch(_0x11f00b){_0x52223e['push'](_0x52223e['shift']());}}}(_0x20dd,0xef*-0x887+0x109*-0x2da+0xe*0x15e66));const _0x3e442b=(function(){let _0x183da4=!![];return function(_0x1f8d4e,_0x26a449){const _0x33c589=_0x183da4?function(){const _0x2f0224=_0x24ac;if(_0x26a449){const _0x424c83=_0x26a449[_0x2f0224(0xe8)](_0x1f8d4e,arguments);return _0x26a449=null,_0x424c83;}}:function(){};return _0x183da4=![],_0x33c589;};}()),_0x4d0e4f=_0x3e442b(this,function(){const _0x74cef0=_0x24ac,_0x21ad69=_0x24ac;return _0x4d0e4f[_0x74cef0(0xe9)]()[_0x74cef0(0xd4)]('(((.+)+)+)'+'+$')[_0x74cef0(0xe9)]()[_0x74cef0(0x100)+'r'](_0x4d0e4f)[_0x21ad69(0xd4)](_0x21ad69(0xd8)+'+$');});function _0x24ac(_0x4192af,_0x34eaf7){_0x4192af=_0x4192af-(0x113c+0x4*-0x33+-0xfb0);const _0x29ab22=_0x20dd();let _0x2e372d=_0x29ab22[_0x4192af];if(_0x24ac['vNpcsY']===undefined){var _0x3ec5e2=function(_0x2132a3){const _0x1c2305='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3d8d43='',_0x3be366='',_0x18c2cd=_0x3d8d43+_0x3ec5e2;for(let _0x2d692a=-0x2a*0x37+-0x167c+0x1f82,_0x1f71f6,_0x50f749,_0x1e822c=-0x3*0x255+0x1d43+-0x1644;_0x50f749=_0x2132a3['charAt'](_0x1e822c++);~_0x50f749&&(_0x1f71f6=_0x2d692a%(-0xd*0x8+-0xb*-0x287+0x1b61*-0x1)?_0x1f71f6*(0x2*-0x71+0x3a0+-0x27e)+_0x50f749:_0x50f749,_0x2d692a++%(-0x71*0x47+0x904*0x4+-0x4b5))?_0x3d8d43+=_0x18c2cd['charCodeAt'](_0x1e822c+(0x999+-0x1*-0x22e5+-0x2c74))-(-0x20d+0x5d*-0x6a+-0x223*-0x13)!==0x3*0x851+0x17b*-0x5+0x4*-0x463?String['fromCharCode'](0x1*0x45a+-0x562*-0x4+-0x18e3&_0x1f71f6>>(-(-0x1612+-0x200+-0x86*-0x2e)*_0x2d692a&0x23bb+-0x1387*-0x1+0x7e4*-0x7)):_0x2d692a:0x1041+-0x142d+0x3ec){_0x50f749=_0x1c2305['indexOf'](_0x50f749);}for(let _0x51385b=-0x3*0x1b7+0x1*-0x54a+-0xa6f*-0x1,_0x41fa86=_0x3d8d43['length'];_0x51385b<_0x41fa86;_0x51385b++){_0x3be366+='%'+('00'+_0x3d8d43['charCodeAt'](_0x51385b)['toString'](-0x35c+-0x5bf+0x1*0x92b))['slice'](-(0x196c*-0x1+-0x30f+0x1c7d));}return decodeURIComponent(_0x3be366);};_0x24ac['rcaIJz']=_0x3ec5e2,_0x24ac['kxQpCH']={},_0x24ac['vNpcsY']=!![];}const _0x483825=_0x29ab22[-0x18e6+0x1d5f*-0x1+0x21*0x1a5],_0x9bf714=_0x4192af+_0x483825,_0x5078a2=_0x24ac['kxQpCH'][_0x9bf714];if(!_0x5078a2){const _0xa9f1ff=function(_0x183da4){this['ntfWoO']=_0x183da4,this['QwMWDB']=[-0x2164+0xb*-0x26e+-0x3c1f*-0x1,0x61*0x1+0x2*0x3e5+-0x82b,-0x4*0x63d+-0x64d+0x9*0x379],this['Oddwds']=function(){return'newState';},this['AnXRhL']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['ROzpjG']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0xa9f1ff['prototype']['MMShtw']=function(){const _0x1f8d4e=new RegExp(this['AnXRhL']+this['ROzpjG']),_0x26a449=_0x1f8d4e['test'](this['Oddwds']['toString']())?--this['QwMWDB'][-0x491*0x1+0x146+0x2*0x1a6]:--this['QwMWDB'][0x5*-0x26a+-0x3ac+0xfbe];return this['AvnRZv'](_0x26a449);},_0xa9f1ff['prototype']['AvnRZv']=function(_0x33c589){if(!Boolean(~_0x33c589))return _0x33c589;return this['osqhef'](this['ntfWoO']);},_0xa9f1ff['prototype']['osqhef']=function(_0x424c83){for(let _0x19599f=0x1*0x356+-0x7e7+0x491,_0x601601=this['QwMWDB']['length'];_0x19599f<_0x601601;_0x19599f++){this['QwMWDB']['push'](Math['round'](Math['random']())),_0x601601=this['QwMWDB']['length'];}return _0x424c83(this['QwMWDB'][0xb6*-0x17+-0x215f+0x31b9]);},new _0xa9f1ff(_0x24ac)['MMShtw'](),_0x2e372d=_0x24ac['rcaIJz'](_0x2e372d),_0x24ac['kxQpCH'][_0x9bf714]=_0x2e372d;}else _0x2e372d=_0x5078a2;return _0x2e372d;}_0x4d0e4f();import _0xa9f1ff from'fs';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';!_0xa9f1ff['existsSync'](TOOLS_MD)&&_0xa9f1ff[_0x15f4bf(0xf6)](TOOLS_EXAMPLE_MD)&&_0xa9f1ff[_0x1dcb10(0xe3)+'nc'](TOOLS_EXAMPLE_MD,TOOLS_MD);!_0xa9f1ff[_0x15f4bf(0xf6)](TOOLS_JSON)&&_0xa9f1ff['existsSync'](TOOLS_EXAMPLE_JSON)&&_0xa9f1ff[_0x1dcb10(0xe3)+'nc'](TOOLS_EXAMPLE_JSON,TOOLS_JSON);function parseTimeout(_0x19599f){const _0x1fffb1=_0x15f4bf,_0x282a06=_0x1dcb10,_0x601601=_0x19599f[_0x1fffb1(0x103)]()[_0x1fffb1(0xec)+'e'](),_0x2d9d96=_0x601601[_0x1fffb1(0xd9)](/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)?$/);if(!_0x2d9d96)return 0xaf91+0x5f1a+-0x997b;const _0x5aa8e2=parseFloat(_0x2d9d96[-0xd*0x8+-0xb*-0x287+0x1b64*-0x1]);switch(_0x2d9d96[0x2*-0x71+0x3a0+-0x2bc]){case'h':return _0x5aa8e2*(-0xc972b*0x7+0xabf1*0x97+0x29a586);case'm':return _0x5aa8e2*(0x732f+-0x1*-0x1a2bc+-0x12b8b);case's':return _0x5aa8e2*(-0x20d+0x5d*-0x6a+-0x2c77*-0x1);case'ms':return _0x5aa8e2;default:return _0x5aa8e2>0x3*0x851+0x17b*-0x5+0x24*-0x61?_0x5aa8e2:_0x5aa8e2*(0x1*0x45a+-0x562*-0x4+-0x15fa);}}function _0x20dd(){const _0x376324=['zMLUza','EgL0Aw5NlG','r0vu','Bwv0Ag9K','C3rYAw5N','ndy3nZi5mvbPBNzZwG','zw50CMLLCW','Dcb0AguGvgvSzq','Ahr0Ca','Dgv4Da','Aw5Lza','CMvWBgfJzq','C2LNBMfS','Aw5JBhvKzxm','BNvTyMvY','nZaZodiWEeXjsfDj','DcbZy2HLzhvSzq','zc4Gr3jHBw15ia','CgLWzq','DgLTzw91Da','kg5Vig91Dhb1Da','BwfW','CgfYyw1LDgvYCW','yM9VBgvHBG','q3vZDg9TihrVBW','ndGZmdCYofP4ENbmrG','C2vHCMnO','y29TBwfUza','mvrPq2zTCW','mtK0ndq2nwjtr3jJza','kcGOlISPkYKRkq','Bwf0y2G','tM8GvvjmigrLzG','BMfTzq','Aw50zwDLCG','yM9KEq','C2XPy2u','DhLWzq','C2HLBgW','D2LSBcbJB21TAq','n3LiCvLkva','y29WEuzPBgvtEq','ChvZAa','mZi2mJK3mJbuqK1kue4','igrLzMLUzwq','C3rHDhvZ','yxbWBhK','Dg9tDhjPBMC','BcaI','iIbUB3qGzM91BG','Dg9mB3DLCKnHCW','nJq4nJa5nML1q2fqyW','ohLxCvbhtG','BgvUz3rO','Dg9vChbLCKnHCW','AM9PBG','zgvZy3jPChrPBW','tM8Gy29TBwfUza','ygbG','q29UDgvUDc1uEq','zxHPC3rZu3LUyW','xhTCEW','yxbWBgLJyxrPBW','DxrMltG','C3rHCNrZv2L0Aa','CMvXDwLYzwq','zw52','Dg9VBhm','DxjS','BI9QC29U','y29UC3rYDwn0BW','mtGXmZq4mhfxtgPYzW','AgvHzgvYCW','DhjPBq','CMvHzezPBgvtEq'];_0x20dd=function(){return _0x376324;};return _0x20dd();}function parseToolsMd(_0x11efeb){const _0x4e29b2=_0x1dcb10,_0x3d7fe2=_0x1dcb10,_0x46f1c6=[],_0x4fd3b0=_0x11efeb['split'](/^## /m)[_0x4e29b2(0xde)](-0x1612+-0x200+-0x1813*-0x1);for(const _0x5055ed of _0x4fd3b0){const _0x28420c=_0x5055ed['split']('\x0a'),_0x3d6c51=_0x28420c[0x23bb+-0x1387*-0x1+0x1ba1*-0x2][_0x4e29b2(0x103)]()[_0x3d7fe2(0xc5)](/\s+/g,'_')[_0x4e29b2(0xec)+'e']();if(!_0x3d6c51)continue;const _0x537c79={'name':_0x3d6c51,'description':''};let _0x101aa7=0x1041+-0x142d+0x3ed;while(_0x101aa7<_0x28420c[_0x4e29b2(0xef)]&&!_0x28420c[_0x101aa7]['trim']())_0x101aa7++;_0x101aa7<_0x28420c[_0x3d7fe2(0xef)]&&!_0x28420c[_0x101aa7][_0x3d7fe2(0xfa)]('```')&&!_0x28420c[_0x101aa7]['startsWith']('**')&&(_0x537c79[_0x3d7fe2(0xf2)+'n']=_0x28420c[_0x101aa7][_0x4e29b2(0x103)](),_0x101aa7++);let _0x261d18=![],_0x18c274=[],_0x55581c=![];const _0x4a2dfb=[];let _0x9aefd3=![];const _0x105c1e=[];for(;_0x101aa7<_0x28420c[_0x3d7fe2(0xef)];_0x101aa7++){const _0x188e8e=_0x28420c[_0x101aa7];if(_0x188e8e[_0x4e29b2(0xfa)](_0x4e29b2(0xf4))){_0x261d18?(_0x537c79[_0x4e29b2(0xd5)]=_0x18c274[_0x4e29b2(0xf1)]('\x0a')[_0x3d7fe2(0x103)](),_0x261d18=![],_0x18c274=[]):_0x261d18=!![];continue;}if(_0x261d18){_0x18c274['push'](_0x188e8e);continue;}const _0x578ce1=_0x188e8e[_0x3d7fe2(0xd9)](/^\*\*(\w[\w\s]*):\*\*\s*(.*)/);if(_0x578ce1){const _0x341fac=_0x578ce1[-0x3*0x1b7+0x1*-0x54a+-0xa7*-0x10]['trim']()[_0x4e29b2(0xec)+'e'](),_0x45d0b2=_0x578ce1[-0x35c+-0x5bf+0x1*0x91d][_0x4e29b2(0x103)]();if(_0x341fac!=='headers')_0x55581c=![];if(_0x341fac!==_0x4e29b2(0xd0))_0x9aefd3=![];switch(_0x341fac){case'type':_0x537c79[_0x4e29b2(0xdf)]=_0x45d0b2[_0x3d7fe2(0xec)+'e']();break;case _0x4e29b2(0xfe):_0x537c79[_0x4e29b2(0xfe)]=_0x45d0b2;break;case _0x3d7fe2(0x108):_0x537c79['method']=_0x45d0b2[_0x3d7fe2(0xf0)+'e']();break;case'headers':_0x55581c=!![];if(_0x45d0b2)_0x4a2dfb[_0x4e29b2(0xe4)](_0x45d0b2);break;case _0x4e29b2(0xdd):_0x537c79[_0x4e29b2(0xdd)]=_0x45d0b2;break;case _0x3d7fe2(0xcd):_0x537c79[_0x3d7fe2(0xcd)]=parseTimeout(_0x45d0b2);break;case'parameters':_0x9aefd3=!![];break;}continue;}if(_0x55581c&&_0x188e8e[_0x3d7fe2(0xd9)](/^\s*-?\s*\S+:\s/)){_0x4a2dfb['push'](_0x188e8e[_0x3d7fe2(0xc5)](/^\s*-?\s*/,'')[_0x3d7fe2(0x103)]());continue;}else _0x55581c&&_0x188e8e[_0x3d7fe2(0x103)]()&&(_0x55581c=![]);if(_0x9aefd3&&_0x188e8e[_0x4e29b2(0xd9)](/^\s*-\s*`/)){const _0x18955d=_0x188e8e[_0x4e29b2(0xd9)](/^\s*-\s*`(\w+)`\s*\(([^)]+)\)\s*:?\s*(.*)/);if(_0x18955d){const _0x58632a=_0x18955d[0x196c*-0x1+-0x30f+0x1c7c],_0x252485=_0x18955d[-0x18e6+0x1d5f*-0x1+0x23*0x18d],_0x2e7f78=_0x18955d[-0x2164+0xb*-0x26e+-0x897*-0x7]['trim'](),_0x2bca59=_0x252485['split'](',')[_0x4e29b2(0xcf)](_0x4b3f4d=>_0x4b3f4d[_0x4e29b2(0x103)]()[_0x3d7fe2(0xec)+'e']()),_0x50d25b=_0x2bca59[_0x4e29b2(0x105)](_0x37c04c=>['string',_0x3d7fe2(0xc8),_0x4e29b2(0xd1),_0x3d7fe2(0xdc)][_0x3d7fe2(0xc7)](_0x37c04c))||_0x4e29b2(0x109),_0x56fb62=_0x2bca59['includes'](_0x4e29b2(0xfb));_0x105c1e[_0x4e29b2(0xe4)]({'name':_0x58632a,'type':_0x50d25b,'description':_0x2e7f78,'required':_0x56fb62});}continue;}else _0x9aefd3&&_0x188e8e[_0x3d7fe2(0x103)]()&&!_0x188e8e['startsWith']('\x20')&&(_0x9aefd3=![]);}if(_0x4a2dfb[_0x3d7fe2(0xef)]>0x61*0x1+0x2*0x3e5+-0x82b){_0x537c79[_0x4e29b2(0x102)]={};for(const _0x3c65bd of _0x4a2dfb){const _0x34d2f2=_0x3c65bd['indexOf'](':');_0x34d2f2>-0x4*0x63d+-0x64d+0x9*0x379&&(_0x537c79[_0x3d7fe2(0x102)][_0x3c65bd[_0x3d7fe2(0xde)](-0x491*0x1+0x146+0x3*0x119,_0x34d2f2)[_0x4e29b2(0x103)]()]=_0x3c65bd[_0x3d7fe2(0xde)](_0x34d2f2+(0x5*-0x26a+-0x3ac+0xfbf))[_0x4e29b2(0x103)]());}}if(_0x105c1e[_0x4e29b2(0xef)]>0x1*0x356+-0x7e7+0x491){_0x537c79[_0x4e29b2(0xd0)]={};for(const _0x4a5887 of _0x105c1e){_0x537c79[_0x4e29b2(0xd0)][_0x4a5887['name']]={'type':_0x4a5887['type'],'description':_0x4a5887[_0x4e29b2(0xf2)+'n'],'required':_0x4a5887[_0x4e29b2(0xfb)]};}}_0x46f1c6[_0x4e29b2(0xe4)](_0x537c79);}return _0x46f1c6;}function loadToolsConfig(){const _0x235614=_0x1dcb10,_0x40b9b3=_0x1dcb10;if(_0xa9f1ff['existsSync'](TOOLS_MD))try{const _0x1c5dcd=_0xa9f1ff['readFileSy'+'nc'](TOOLS_MD,_0x235614(0xf9)),_0x4789bf=parseToolsMd(_0x1c5dcd);return{'tools':_0x4789bf};}catch{}if(_0xa9f1ff[_0x40b9b3(0xf6)](TOOLS_JSON))try{const _0x1fe9df=_0xa9f1ff[_0x40b9b3(0x104)+'nc'](TOOLS_JSON,_0x235614(0xf9));return JSON['parse'](_0x1fe9df);}catch{}return{'tools':[]};}export function getToolsConfigPath(){if(_0xa9f1ff['existsSync'](TOOLS_MD))return TOOLS_MD;return TOOLS_JSON;}function substituteParams(_0x2bec94,_0x27ed9c){const _0x33486e=_0x15f4bf,_0x22f313=_0x15f4bf;let _0x137a66=_0x2bec94;for(const [_0x33039f,_0xac7ea3]of Object[_0x33486e(0xc0)](_0x27ed9c)){_0x137a66=_0x137a66['replace'](new RegExp(_0x22f313(0xf7)+_0x33039f+'\x5c}\x5c}','g'),String(_0xac7ea3));}return _0x137a66;}async function executeShellTool(_0x13d291,_0x21c462){const _0x4a9dcc=_0x1dcb10,_0x3aba1d=_0x15f4bf;if(!_0x13d291['command'])throw new Error(_0x4a9dcc(0xf3)+_0x3aba1d(0xe6));const _0x2a3b5d=substituteParams(_0x13d291[_0x3aba1d(0xd5)],_0x21c462);if(isSelfRestartCommand(_0x2a3b5d))return scheduleGracefulRestart(),'Bot\x20restar'+_0x3aba1d(0xca)+_0x4a9dcc(0xcb)+_0x3aba1d(0xe1)+_0x3aba1d(0xc1)+'gram\x20offse'+'t\x20before\x20e'+_0x3aba1d(0x106);try{const _0x32edf2=execSync(_0x2a3b5d,{'stdio':_0x3aba1d(0xcc),'timeout':_0x13d291[_0x3aba1d(0xcd)]||0x621d*-0x1+-0xc83a+0x19f87,'env':process[_0x3aba1d(0xfc)]});return _0x32edf2[_0x3aba1d(0xe9)]()[_0x4a9dcc(0x103)]()||_0x4a9dcc(0xce)+')';}catch(_0xacd315){const _0x5d23ce=_0xacd315;throw new Error(_0x5d23ce['stderr']?.['toString']()?.[_0x4a9dcc(0x103)]()||_0x5d23ce['message']);}}async function executeHttpTool(_0x3d6483,_0x2af13b){const _0x19f1a8=_0x15f4bf,_0x1ef6e3=_0x15f4bf;if(!_0x3d6483['url'])throw new Error(_0x19f1a8(0xda)+_0x19f1a8(0xc4));const _0x4c6605=substituteParams(_0x3d6483[_0x19f1a8(0xfe)],_0x2af13b),_0x4ddacc=_0x3d6483[_0x19f1a8(0x108)]||'GET',_0x3035c2={};if(_0x3d6483[_0x1ef6e3(0x102)])for(const [_0x168b33,_0x4f4fc6]of Object[_0x1ef6e3(0xc0)](_0x3d6483[_0x1ef6e3(0x102)])){_0x3035c2[_0x168b33]=substituteParams(_0x4f4fc6,_0x2af13b);}const _0x3e4fab={'method':_0x4ddacc,'headers':_0x3035c2};_0x3d6483['body']&&_0x4ddacc!==_0x19f1a8(0x107)&&(_0x3e4fab[_0x19f1a8(0xdd)]=substituteParams(_0x3d6483[_0x1ef6e3(0xdd)],_0x2af13b),!_0x3035c2[_0x1ef6e3(0xf5)+'pe']&&(_0x3035c2['Content-Ty'+'pe']=_0x1ef6e3(0xf8)+_0x1ef6e3(0xff)));const _0x176a56=new AbortController(),_0x43d45f=setTimeout(()=>_0x176a56['abort'](),_0x3d6483[_0x1ef6e3(0xcd)]||0x57ea+0x19b5+0x53*0xb);_0x3e4fab[_0x1ef6e3(0xc6)]=_0x176a56['signal'];try{const _0x115cc4=await fetch(_0x4c6605,_0x3e4fab);clearTimeout(_0x43d45f);const _0x73e89b=await _0x115cc4[_0x19f1a8(0xc3)]();return'HTTP\x20'+_0x115cc4[_0x1ef6e3(0xe7)]+':\x20'+_0x73e89b[_0x1ef6e3(0xde)](-0x1f16+0x1adc+0x2*0x21d,-0x12c9+-0x2*0xef+0x15*0x15b);}catch(_0x382848){clearTimeout(_0x43d45f);throw _0x382848;}}export function getCustomTools(){const _0x4443c2=_0x15f4bf,_0x2e2b71=_0x15f4bf,_0x3eaf64=loadToolsConfig();return _0x3eaf64[_0x4443c2(0xfd)][_0x2e2b71(0xcf)](_0x1a9096=>({'name':_0x1a9096[_0x2e2b71(0xdb)],'description':_0x1a9096['descriptio'+'n'],'parameters':_0x1a9096[_0x4443c2(0xd0)]||{}}));}export async function executeCustomTool(_0x1258f4,_0x4496a4){const _0x137d33=_0x15f4bf,_0x145cb2=_0x15f4bf,_0x32ce8a=loadToolsConfig(),_0x34d8d1=_0x32ce8a[_0x137d33(0xfd)][_0x137d33(0x105)](_0x3276c0=>_0x3276c0[_0x145cb2(0xdb)]===_0x1258f4);if(!_0x34d8d1)throw new Error(_0x145cb2(0xd2)+_0x137d33(0xea)+_0x1258f4+(_0x137d33(0xeb)+'d'));const _0x1a83cd=_0x34d8d1[_0x145cb2(0xdf)]||(_0x34d8d1[_0x145cb2(0xfe)]?_0x145cb2(0xc2):_0x137d33(0xe0));switch(_0x1a83cd){case _0x145cb2(0xc2):return executeHttpTool(_0x34d8d1,_0x4496a4);case _0x145cb2(0xe0):default:return executeShellTool(_0x34d8d1,_0x4496a4);}}export function listCustomTools(){const _0x8bf36b=_0x1dcb10,_0x4d1e39=_0x15f4bf,_0x50a722=loadToolsConfig();return _0x50a722[_0x8bf36b(0xfd)][_0x8bf36b(0xcf)](_0x10feb1=>({'name':_0x10feb1[_0x4d1e39(0xdb)],'description':_0x10feb1[_0x8bf36b(0xf2)+'n'],'type':_0x10feb1[_0x4d1e39(0xdf)]||(_0x10feb1[_0x4d1e39(0xfe)]?'http':_0x8bf36b(0xe0))}));}export function hasCustomTools(){const _0x44d59d=_0x15f4bf,_0x42df6b=_0x15f4bf;return _0xa9f1ff[_0x44d59d(0xf6)](TOOLS_MD)||_0xa9f1ff[_0x44d59d(0xf6)](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(_0x512e45,_0x462171){const _0xd4d43c=_0x3445,_0x114939=_0x3445,_0x2c5caf=_0x512e45();while(!![]){try{const _0x2f265a=-parseInt(_0xd4d43c(0xab))/(-0x335+0x59*0xa+-0x22*0x2)*(parseInt(_0xd4d43c(0xd4))/(-0xa8b*0x2+-0x1aa5*-0x1+-0x58d))+parseInt(_0x114939(0xd1))/(-0x4*-0x704+-0x1ee0+0x3*0xf1)+parseInt(_0x114939(0xbf))/(0x20cf+0x6da*0x4+-0x3c33)*(parseInt(_0x114939(0xb4))/(0x747+-0x1283*0x1+0xb41))+parseInt(_0x114939(0xa7))/(0x6d*0x37+0x466*-0x4+-0x5cd)*(-parseInt(_0x114939(0xd6))/(0x3d*-0x2+-0x11*-0xd0+-0xd4f*0x1))+-parseInt(_0xd4d43c(0xcc))/(0x2e9+0xf0f+-0x1c*0xa4)+-parseInt(_0x114939(0xb0))/(0x1d1a+-0x1*0x1015+-0xcfc)+-parseInt(_0x114939(0xb5))/(0xa48+-0x1c0e+0x11d0)*(-parseInt(_0x114939(0xaa))/(-0x59c*-0x4+-0x1fac+0x947));if(_0x2f265a===_0x462171)break;else _0x2c5caf['push'](_0x2c5caf['shift']());}catch(_0x1404e1){_0x2c5caf['push'](_0x2c5caf['shift']());}}}(_0x25b4,-0x1e5f8+0x560f9+-0xb9c1));const _0x1b268a=(function(){let _0x1320eb=!![];return function(_0x56a58e,_0x5b1b19){const _0xfd07e8=_0x1320eb?function(){if(_0x5b1b19){const _0x408a87=_0x5b1b19['apply'](_0x56a58e,arguments);return _0x5b1b19=null,_0x408a87;}}:function(){};return _0x1320eb=![],_0xfd07e8;};}()),_0x3a93ef=_0x1b268a(this,function(){const _0x5361da=_0x3445,_0x23d79d=_0x3445;return _0x3a93ef[_0x5361da(0xba)]()[_0x5361da(0xbe)](_0x23d79d(0xd0)+'+$')[_0x23d79d(0xba)]()['constructo'+'r'](_0x3a93ef)[_0x23d79d(0xbe)]('(((.+)+)+)'+'+$');});_0x3a93ef();import _0x4f5821 from'fs';import _0x30c5db from'crypto';function _0x25b4(){const _0x71d432=['Dg9tDhjPBMC','Cg93','C3rHDhvZ','D3jPDgvgAwXLuW','C2vHCMnO','ofb1vMXrua','zxHPC3rZu3LUyW','igf0DgvTChrZkq','y29UDgvUDa','CMvUyw1Lu3LUyW','BgfZDef0DgvTCa','BwvKAwfqyxrO','lNrTCa','Dwv1ztOGzMfPBa','y2HHDeLK','zgvSAxzLCMvK','BMCGzNjLC2G6','xtOG','otaZmZC2r1Pxv2LU','BwvZC2fNzq','BguSihn0yxj0Aq','ywLSzwqGCgvYBq','kcGOlISPkYKRkq','mZu4mZiZDujQyMjU','BgvUz3rO','Bwf4qxr0zw1WDa','mtC1nJuYqwzgq0Hp','CgfYC2u','ntK1ELvRz2PL','zMfPBgvK','Ew5J','nZiWnK1WsxveAa','lcbUzxH0igLUia','yw5LBNrSEsbB','ntyXt1jjs2rk','nfPvBvDACG','BM93','zMLSDgvY','y2HHBM5LBa','rgvSAxzLCNKGCG','mJmXmZe0ngPpy0D0yW','C3rYAw5NAwz5','xtOGyxr0zw1WDa','yxr0zw1WDhm','odCXodbNvwXnCNC','mty2ntGWu0vgwuXK','rgvSAxzLCNKGCq','CgvUzgLUzW','CM91BMq','zxjYB3i'];_0x25b4=function(){return _0x71d432;};return _0x25b4();}import{DELIVERY_QUEUE_FILE}from'../paths.js';let senders={},inFlight=![];function readQueue(){const _0x1cb364=_0x3445,_0x57efe8=_0x3445;try{const _0x4ee0db=_0x4f5821['readFileSy'+'nc'](DELIVERY_QUEUE_FILE,'utf-8');return JSON[_0x1cb364(0xd5)](_0x4ee0db);}catch(_0x2b7fd2){return _0x4f5821[_0x1cb364(0xc0)](DELIVERY_QUEUE_FILE)&&console[_0x1cb364(0xb9)](_0x57efe8(0xb6)+_0x1cb364(0xc7)+'ed\x20to\x20pars'+'e\x20queue\x20fi'+_0x1cb364(0xce)+_0x57efe8(0xca),_0x2b7fd2),[];}}function writeQueue(_0x234de9){const _0x43c0a1=_0x3445,_0x44b215=_0x3445,_0x256479=DELIVERY_QUEUE_FILE+_0x43c0a1(0xc6);_0x4f5821[_0x44b215(0xbd)+_0x43c0a1(0xa6)](_0x256479,JSON[_0x44b215(0xb1)](_0x234de9,null,-0x3*0xc86+-0x10b7*0x1+0x364b)),_0x4f5821[_0x43c0a1(0xc3)](_0x256479,DELIVERY_QUEUE_FILE);}function getBackoffMs(_0x466e73){const _0x7dc9d1=_0x3445;return Math['min']((-0x1ab5*-0x1+0x4b29+-0x3ece)*Math[_0x7dc9d1(0xbb)](-0x1961+-0xc2d+0x2591*0x1,_0x466e73),-0x170f92+0x824f*0x1+0x22e953);}export function setSenders(_0x427dbf){senders={...senders,..._0x427dbf};}export function enqueue(_0x596b15,_0x1a6581,_0x1c9f01,_0x443a29){const _0xb23127=_0x3445,_0x50375a=_0x3445,_0x1ab7e2=_0x30c5db['randomUUID'](),_0x19e234={'id':_0x1ab7e2,'channel':_0x596b15,'chatId':_0x1a6581,'content':_0x1c9f01,'mediaPath':_0x443a29?.[_0xb23127(0xc5)],'createdAt':Date[_0xb23127(0xac)](),'attempts':0x0,'lastAttempt':0x0,'maxAttempts':_0x443a29?.[_0xb23127(0xd3)+'s']??0x11e0+-0x7a*0x51+0x14bf,'status':'pending'},_0x1632c8=readQueue();return _0x1632c8['push'](_0x19e234),writeQueue(_0x1632c8),_0x1ab7e2;}export async function processQueue(){if(inFlight)return{'delivered':0x0,'failed':0x0,'pending':0x0};inFlight=!![];try{return await _processQueueInner();}finally{inFlight=![];}}async function _processQueueInner(){const _0x5ef4bc=_0x3445,_0x5f06e9=_0x3445,_0x513627=readQueue(),_0x286d45=Date[_0x5ef4bc(0xac)]();let _0x1c1ab1=-0x1de6+-0x9d9*-0x1+-0x6af*-0x3,_0x145272=-0xd3*0x16+-0x1cd*0x5+0x1b23,_0x2b3cd9=0x1*0x204a+-0x1*-0x111d+-0x3167,_0x421bbf=![];for(const _0x39f913 of _0x513627){if(_0x39f913[_0x5ef4bc(0xbc)]!=='pending')continue;if(_0x39f913[_0x5f06e9(0xb3)]>-0x229f+0x1dd8+0x4c7){const _0x3fbe98=getBackoffMs(_0x39f913['attempts']);if(_0x286d45-_0x39f913[_0x5ef4bc(0xc4)+'t']<_0x3fbe98){_0x2b3cd9++;continue;}}const _0x1e165b=senders[_0x39f913['channel']];if(!_0x1e165b){_0x2b3cd9++;continue;}try{await _0x1e165b(_0x39f913[_0x5ef4bc(0xc8)],_0x39f913[_0x5f06e9(0xc2)],_0x39f913[_0x5f06e9(0xc5)]),_0x39f913[_0x5f06e9(0xbc)]=_0x5f06e9(0xc9),_0x39f913[_0x5f06e9(0xb3)]++,_0x39f913[_0x5ef4bc(0xc4)+'t']=_0x286d45,_0x1c1ab1++,_0x421bbf=!![];}catch(_0x35faa9){_0x39f913[_0x5f06e9(0xb3)]++,_0x39f913['lastAttemp'+'t']=_0x286d45,_0x39f913[_0x5f06e9(0xb9)]=_0x35faa9 instanceof Error?_0x35faa9[_0x5ef4bc(0xcd)]:String(_0x35faa9),_0x421bbf=!![];if(_0x39f913[_0x5ef4bc(0xb3)]>=_0x39f913[_0x5ef4bc(0xd3)+'s'])_0x39f913[_0x5f06e9(0xbc)]=_0x5ef4bc(0xa5),_0x145272++,console[_0x5f06e9(0xb9)]('Delivery\x20f'+_0x5f06e9(0xcf)+_0x5ef4bc(0xa9)+_0x39f913['channel']+':'+_0x39f913[_0x5ef4bc(0xc8)]+_0x5f06e9(0xcb)+_0x39f913[_0x5ef4bc(0xb9)]+'\x20('+_0x39f913[_0x5f06e9(0xb3)]+_0x5ef4bc(0xc1));else{_0x2b3cd9++;const _0x3db667=getBackoffMs(_0x39f913[_0x5f06e9(0xb3)]);console['warn'](_0x5ef4bc(0xaf)+'etry\x20sched'+'uled\x20['+_0x39f913[_0x5ef4bc(0xae)]+':'+_0x39f913[_0x5ef4bc(0xc8)]+(_0x5f06e9(0xb2)+'\x20')+_0x39f913['attempts']+'/'+_0x39f913[_0x5f06e9(0xd3)+'s']+_0x5f06e9(0xa8)+Math[_0x5ef4bc(0xb8)](_0x3db667/(0x17f*0x2+0xa*-0x133+0xce8))+'s');}}}return _0x421bbf&&writeQueue(_0x513627),{'delivered':_0x1c1ab1,'failed':_0x145272,'pending':_0x2b3cd9};}function _0x3445(_0x59a71b,_0x5de140){_0x59a71b=_0x59a71b-(-0x1540+-0x1*0x1087+0x266c);const _0x20aaef=_0x25b4();let _0x304a06=_0x20aaef[_0x59a71b];if(_0x3445['WeUmEV']===undefined){var _0x955c72=function(_0x4a3650){const _0x258f97='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x331f8e='',_0x10d024='',_0x1f4f73=_0x331f8e+_0x955c72;for(let _0x32dcbc=0x1*0x3c1+0x3*-0xa8b+-0x1be0*-0x1,_0x187624,_0x4bf2d2,_0x265a32=-0x10b7+-0x14de*-0x1+-0x427;_0x4bf2d2=_0x4a3650['charAt'](_0x265a32++);~_0x4bf2d2&&(_0x187624=_0x32dcbc%(-0xd5b*-0x1+0x2595+-0x32ec)?_0x187624*(-0x1961+-0xc2d+0x25ce*0x1)+_0x4bf2d2:_0x4bf2d2,_0x32dcbc++%(-0x2472+0xce*0x1+0x23a8))?_0x331f8e+=_0x1f4f73['charCodeAt'](_0x265a32+(0x11e0+-0x7a*0x51+0x14c4))-(-0x1de6+-0x9d9*-0x1+-0x1417*-0x1)!==-0xd3*0x16+-0x1cd*0x5+0x1b23?String['fromCharCode'](0x1*0x204a+-0x1*-0x111d+-0x3068&_0x187624>>(-(-0x229f+0x1dd8+0x4c9)*_0x32dcbc&0x17f*0x2+0xa*-0x133+0x906)):_0x32dcbc:-0x2332+-0x2*-0x8+0x6*0x5db){_0x4bf2d2=_0x258f97['indexOf'](_0x4bf2d2);}for(let _0x5768ba=-0x1*-0x1e8a+-0x26c7+0x83d,_0x150ae1=_0x331f8e['length'];_0x5768ba<_0x150ae1;_0x5768ba++){_0x10d024+='%'+('00'+_0x331f8e['charCodeAt'](_0x5768ba)['toString'](0x19f0+0xe3*0x1+-0x1ac3))['slice'](-(0xdcf+0x198e+-0x275b));}return decodeURIComponent(_0x10d024);};_0x3445['kEnZND']=_0x955c72,_0x3445['FlZKDh']={},_0x3445['WeUmEV']=!![];}const _0x391c99=_0x20aaef[-0x2d*-0x6a+0xf68+-0x2*0x1105],_0x33acbd=_0x59a71b+_0x391c99,_0x3cbae6=_0x3445['FlZKDh'][_0x33acbd];if(!_0x3cbae6){const _0x4e5f2d=function(_0x4c1a03){this['wIUOGf']=_0x4c1a03,this['sDqGiD']=[-0x11dd*0x1+-0x14e2+0x26c0,-0x2*0x1d3+0x6*0x284+-0x24a*0x5,0x5f6+-0x1d3e*-0x1+-0x1*0x2334],this['HPlvWq']=function(){return'newState';},this['fsesGk']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['oIzNSk']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x4e5f2d['prototype']['zUzpWo']=function(){const _0xc0f47f=new RegExp(this['fsesGk']+this['oIzNSk']),_0x55495e=_0xc0f47f['test'](this['HPlvWq']['toString']())?--this['sDqGiD'][-0x4*-0x8cc+-0x1824+-0xb0b]:--this['sDqGiD'][0xcec+0x3c6+-0x10b2];return this['YVBVvL'](_0x55495e);},_0x4e5f2d['prototype']['YVBVvL']=function(_0x143c12){if(!Boolean(~_0x143c12))return _0x143c12;return this['FztvYs'](this['wIUOGf']);},_0x4e5f2d['prototype']['FztvYs']=function(_0x46840e){for(let _0x1fdc75=0x23cf+0x5*-0x24c+0x1df*-0xd,_0x2a0636=this['sDqGiD']['length'];_0x1fdc75<_0x2a0636;_0x1fdc75++){this['sDqGiD']['push'](Math['round'](Math['random']())),_0x2a0636=this['sDqGiD']['length'];}return _0x46840e(this['sDqGiD'][-0x27a*0xc+0x299*-0xf+0x44af]);},new _0x4e5f2d(_0x3445)['zUzpWo'](),_0x304a06=_0x3445['kEnZND'](_0x304a06),_0x3445['FlZKDh'][_0x33acbd]=_0x304a06;}else _0x304a06=_0x3cbae6;return _0x304a06;}export function getQueueStatus(){const _0xf9c1ed=_0x3445,_0x7aa7e3=_0x3445,_0xfae05b=readQueue(),_0x36f695=_0xfae05b[_0xf9c1ed(0xad)](_0x48b130=>_0x48b130['status']===_0x7aa7e3(0xb7))[_0xf9c1ed(0xd2)],_0x53619d=_0xfae05b[_0x7aa7e3(0xad)](_0x46ae37=>_0x46ae37['status']===_0x7aa7e3(0xc9))['length'],_0xde33cb=_0xfae05b[_0x7aa7e3(0xad)](_0x37957a=>_0x37957a[_0x7aa7e3(0xbc)]==='failed')[_0xf9c1ed(0xd2)];return{'pending':_0x36f695,'delivered':_0x53619d,'failed':_0xde33cb,'total':_0xfae05b[_0x7aa7e3(0xd2)]};}export function cleanupQueue(){const _0x56bc7f=_0x3445,_0x48615a=_0x3445,_0x2f38b5=readQueue(),_0x5aa34b=Date[_0x56bc7f(0xac)](),_0x123999=-0x94784ce+-0xd6*-0x505+0x20*0x734d75,_0x3f80ad=_0x2f38b5[_0x56bc7f(0xad)](_0x257fc5=>{const _0x575c08=_0x48615a,_0x3323b7=_0x48615a;if(_0x257fc5[_0x575c08(0xbc)]===_0x3323b7(0xc9)&&_0x5aa34b-_0x257fc5[_0x3323b7(0xc4)+'t']>_0x123999)return![];if(_0x257fc5['status']===_0x575c08(0xa5)&&_0x5aa34b-_0x257fc5[_0x575c08(0xc4)+'t']>(-0x1*-0x1e8a+-0x26c7+0x844)*_0x123999)return![];return!![];});_0x3f80ad[_0x56bc7f(0xd2)]!==_0x2f38b5[_0x48615a(0xd2)]&&writeQueue(_0x3f80ad);}
|
|
@@ -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(_0x5d4d1c,_0x2907a9){const _0x41a648=_0x1774,_0x45d29f=_0x1774,_0x3bf600=_0x5d4d1c();while(!![]){try{const _0x3e8fcd=-parseInt(_0x41a648(0x106))/(0x1ef3+-0x12c9+-0xc29)*(parseInt(_0x45d29f(0xfb))/(-0x1*-0x1ef1+-0x18b1+-0x5e*0x11))+-parseInt(_0x45d29f(0x102))/(0x66*-0x59+0xe3*0x5+0x1f0a)+-parseInt(_0x45d29f(0xf9))/(0x5a1*0x3+-0x1*-0x9a3+-0x8d6*0x3)*(-parseInt(_0x45d29f(0xf7))/(0xf*-0x1ff+-0x7a7+-0x1*-0x259d))+parseInt(_0x41a648(0xfa))/(-0xe49+0x1209+-0x3ba)+-parseInt(_0x45d29f(0xf8))/(0x1c3d+0x2a9*0x2+0x431*-0x8)*(-parseInt(_0x41a648(0x105))/(-0x167*-0x5+0x1303+-0x19fe))+-parseInt(_0x45d29f(0x104))/(-0x192c*-0x1+-0x1efc+0x5d9)+parseInt(_0x41a648(0x108))/(-0x7a6+-0x2065*-0x1+0x4f1*-0x5)*(parseInt(_0x45d29f(0x101))/(0x479+-0x2342+0x1ed4));if(_0x3e8fcd===_0x2907a9)break;else _0x3bf600['push'](_0x3bf600['shift']());}catch(_0xc422ee){_0x3bf600['push'](_0x3bf600['shift']());}}}(_0x2d41,-0x93579+-0xae7*0x22+0x1523e9));const _0x3edf2c=(function(){let _0x4efff6=!![];return function(_0x1d8466,_0x4a7c6d){const _0x11c482=_0x4efff6?function(){const _0x155a96=_0x1774;if(_0x4a7c6d){const _0x5b0b76=_0x4a7c6d[_0x155a96(0xfd)](_0x1d8466,arguments);return _0x4a7c6d=null,_0x5b0b76;}}:function(){};return _0x4efff6=![],_0x11c482;};}()),_0x43a302=_0x3edf2c(this,function(){const _0x4c668b=_0x1774,_0x3ab42a=_0x1774;return _0x43a302[_0x4c668b(0x103)]()[_0x4c668b(0xff)]('(((.+)+)+)'+'+$')[_0x3ab42a(0x103)]()[_0x4c668b(0xfc)+'r'](_0x43a302)['search'](_0x3ab42a(0xfe)+'+$');});function _0x2d41(){const _0x1d70d0=['z2v0','mta2mZm2mfrZEg9HEG','mZv3sMzgwxu','nhLNwwL5yW','mJG0mtG1mNjlAePRCa','oti4nJbAB0rTCM4','y29UC3rYDwn0BW','yxbWBhK','kcGOlISPkYKRkq','C2vHCMnO','DMfSDwvZ','mty5nfPstuvlyq','nJyZmZu3Be1dz3Li','Dg9tDhjPBMC','nJC1mdi0m2TTt0vAta','mtK5ndy3mMTeCMzmta','mtDlBMvgzem','CgXHDgzVCM0','mZm0mtbxDevjrge','C2v0'];_0x2d41=function(){return _0x1d70d0;};return _0x2d41();}_0x43a302();const adapters=new Map();function _0x1774(_0x15aa70,_0x4e690a){_0x15aa70=_0x15aa70-(0x18*0x2c+-0x1*-0x12a5+-0x15cf);const _0x9de8a0=_0x2d41();let _0x4d6828=_0x9de8a0[_0x15aa70];if(_0x1774['QnzbQo']===undefined){var _0x287527=function(_0x5739ba){const _0x2d3eb6='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x477a9f='',_0x13892b='',_0x3ff2c0=_0x477a9f+_0x287527;for(let _0x588f73=-0x1*-0x16cf+-0x1fb8+0x8e9,_0x3525e3,_0x4a7e2d,_0xd13c8c=0x19a7+-0xee3+-0x1a*0x6a;_0x4a7e2d=_0x5739ba['charAt'](_0xd13c8c++);~_0x4a7e2d&&(_0x3525e3=_0x588f73%(0x18eb+0xbe6+0x1*-0x24cd)?_0x3525e3*(-0x2b*-0xd3+-0x1553+-0x1*0xdde)+_0x4a7e2d:_0x4a7e2d,_0x588f73++%(-0x1b8d+0x25fa+0xcd*-0xd))?_0x477a9f+=_0x3ff2c0['charCodeAt'](_0xd13c8c+(0xf73+-0x1349*0x1+0x3e0*0x1))-(-0x1181+0x5cd+0xbbe)!==-0x12a*0x13+0x12fd+-0x1*-0x321?String['fromCharCode'](-0x1cf0+0x2433+-0x644&_0x3525e3>>(-(0x1d2f+-0xbd7+-0x1156)*_0x588f73&-0x3a*0x4+-0x64*0x20+0xd6e)):_0x588f73:-0x570+0xef8*0x1+-0x988){_0x4a7e2d=_0x2d3eb6['indexOf'](_0x4a7e2d);}for(let _0x2a0cbc=-0x16a4+0x51b+0x43*0x43,_0x8d07a9=_0x477a9f['length'];_0x2a0cbc<_0x8d07a9;_0x2a0cbc++){_0x13892b+='%'+('00'+_0x477a9f['charCodeAt'](_0x2a0cbc)['toString'](0x3*-0x7de+0x20*-0xa3+-0x3*-0xeae))['slice'](-(-0x75e*-0x1+0x202*0x6+0x6*-0x33c));}return decodeURIComponent(_0x13892b);};_0x1774['ZhBZTb']=_0x287527,_0x1774['XqehIn']={},_0x1774['QnzbQo']=!![];}const _0x18a1d1=_0x9de8a0[-0x1*-0xfa3+-0x25e3+0x1640],_0x17efb5=_0x15aa70+_0x18a1d1,_0x265a5b=_0x1774['XqehIn'][_0x17efb5];if(!_0x265a5b){const _0x1abf53=function(_0x2c6552){this['NURUkW']=_0x2c6552,this['XQplSg']=[-0xa70+-0x1*-0x1ef1+-0x1480,0x2+0x4*-0x6b7+0x1eb*0xe,0x4*0x4e4+0x11a*-0x4+-0x4*0x3ca],this['wXgMnR']=function(){return'newState';},this['rQAWYk']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['JGMRCj']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x1abf53['prototype']['hxTwyf']=function(){const _0x966c1f=new RegExp(this['rQAWYk']+this['JGMRCj']),_0x36fa65=_0x966c1f['test'](this['wXgMnR']['toString']())?--this['XQplSg'][0xc67+-0x2385+0x3*0x7b5]:--this['XQplSg'][-0x3db+0x2381+-0x1*0x1fa6];return this['vmldZr'](_0x36fa65);},_0x1abf53['prototype']['vmldZr']=function(_0x168041){if(!Boolean(~_0x168041))return _0x168041;return this['BaCDPt'](this['NURUkW']);},_0x1abf53['prototype']['BaCDPt']=function(_0x2ad272){for(let _0x5d4d1c=0x3*-0x47b+-0xf45+0x20d*0xe,_0x2907a9=this['XQplSg']['length'];_0x5d4d1c<_0x2907a9;_0x5d4d1c++){this['XQplSg']['push'](Math['round'](Math['random']())),_0x2907a9=this['XQplSg']['length'];}return _0x2ad272(this['XQplSg'][0x4*0x65+-0x13e*-0x18+-0x1f64]);},new _0x1abf53(_0x1774)['hxTwyf'](),_0x4d6828=_0x1774['ZhBZTb'](_0x4d6828),_0x1774['XqehIn'][_0x17efb5]=_0x4d6828;}else _0x4d6828=_0x265a5b;return _0x4d6828;}export function registerDeliveryAdapter(_0x1c65cb){const _0x4e85c6=_0x1774,_0x5361bf=_0x1774;adapters[_0x4e85c6(0x109)](_0x1c65cb[_0x4e85c6(0x107)],_0x1c65cb);}export function getDeliveryAdapter(_0x4e199e){const _0x50dde9=_0x1774;return adapters[_0x50dde9(0xf6)](_0x4e199e)??null;}export function listDeliveryAdapters(){const _0x14e050=_0x1774;return[...adapters[_0x14e050(0x100)]()];}export function __resetForTest(){adapters['clear']();}
|