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
package/dist/web/setup-api.js
CHANGED
|
@@ -1,1101 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Setup API — Platform & Model configuration endpoints.
|
|
3
|
-
*
|
|
4
|
-
* Handles:
|
|
5
|
-
* - Platform setup (Discord, WhatsApp, Signal tokens + dependency installation)
|
|
6
|
-
* - Model/Provider management (API keys, custom models, presets)
|
|
7
|
-
* - Runtime activation/deactivation
|
|
8
|
-
*/
|
|
9
|
-
import fs from "fs";
|
|
10
|
-
import { resolve } from "path";
|
|
11
|
-
import { execSync } from "child_process";
|
|
12
|
-
import { getRegistry } from "../engine.js";
|
|
13
|
-
import { listJobs, createJob, deleteJob, toggleJob, updateJob, runJobNow, formatNextRun, humanReadableSchedule } from "../services/cron.js";
|
|
14
|
-
import { storePassword, revokePassword, getSudoStatus, verifyPassword, sudoExec, requestAdminViaDialog, openSystemSettings } from "../services/sudo.js";
|
|
15
|
-
import { CUSTOM_MODELS as CUSTOM_MODELS_FILE, BOT_ROOT, WHATSAPP_AUTH } from "../paths.js";
|
|
16
|
-
import { readEnv, writeEnvVar, removeEnvVar } from "../services/env-file.js";
|
|
17
|
-
function loadCustomModels() {
|
|
18
|
-
try {
|
|
19
|
-
return JSON.parse(fs.readFileSync(CUSTOM_MODELS_FILE, "utf-8"));
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function saveCustomModels(models) {
|
|
26
|
-
fs.writeFileSync(CUSTOM_MODELS_FILE, JSON.stringify(models, null, 2));
|
|
27
|
-
}
|
|
28
|
-
const PLATFORMS = [
|
|
29
|
-
{
|
|
30
|
-
id: "telegram",
|
|
31
|
-
name: "Telegram",
|
|
32
|
-
icon: "📱",
|
|
33
|
-
description: "Telegram Bot via BotFather. The default messaging channel.",
|
|
34
|
-
envVars: [
|
|
35
|
-
{ key: "BOT_TOKEN", label: "Bot Token", placeholder: "123456:ABC-DEF...", secret: true },
|
|
36
|
-
{ key: "ALLOWED_USERS", label: "Allowed User IDs", placeholder: "123456789,987654321" },
|
|
37
|
-
],
|
|
38
|
-
setupUrl: "https://t.me/BotFather",
|
|
39
|
-
setupSteps: [
|
|
40
|
-
"Open @BotFather on Telegram",
|
|
41
|
-
"Send /newbot and follow the instructions",
|
|
42
|
-
"Copy the bot token here",
|
|
43
|
-
"For your User ID: Send a message to @userinfobot",
|
|
44
|
-
],
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id: "discord",
|
|
48
|
-
name: "Discord",
|
|
49
|
-
icon: "🎮",
|
|
50
|
-
description: "Discord bot for servers and DMs. Requires discord.js.",
|
|
51
|
-
envVars: [
|
|
52
|
-
{ key: "DISCORD_TOKEN", label: "Bot Token", placeholder: "MTIz...abc", secret: true },
|
|
53
|
-
],
|
|
54
|
-
npmPackages: ["discord.js"],
|
|
55
|
-
setupUrl: "https://discord.com/developers/applications",
|
|
56
|
-
setupSteps: [
|
|
57
|
-
"Create an Application on discord.com/developers",
|
|
58
|
-
"Go to Bot → Reset Token → Copy token",
|
|
59
|
-
"Enable Message Content Intent under Bot → Privileged Intents",
|
|
60
|
-
"Invite the bot to your server: OAuth2 → URL Generator → bot + messages.read + messages.write",
|
|
61
|
-
],
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
id: "whatsapp",
|
|
65
|
-
name: "WhatsApp",
|
|
66
|
-
icon: "💬",
|
|
67
|
-
description: "WhatsApp Multi-Device connection via Baileys (no Chrome needed). QR code scan on first start.",
|
|
68
|
-
envVars: [
|
|
69
|
-
{ key: "WHATSAPP_ENABLED", label: "Enable", placeholder: "true", type: "toggle" },
|
|
70
|
-
{ key: "WHATSAPP_SELF_CHAT_ONLY", label: "Self-chat only (recommended)", placeholder: "true", type: "toggle" },
|
|
71
|
-
{ key: "WHATSAPP_ALLOW_GROUPS", label: "Reply in groups (on @mention)", placeholder: "", type: "toggle" },
|
|
72
|
-
{ key: "WHATSAPP_ALLOW_DMS", label: "Reply to private messages", placeholder: "", type: "toggle" },
|
|
73
|
-
],
|
|
74
|
-
npmPackages: ["@whiskeysockets/baileys"],
|
|
75
|
-
setupSteps: [
|
|
76
|
-
"Click 'Install Dependencies' (if needed)",
|
|
77
|
-
"Enable WhatsApp (toggle above) and click 'Save'",
|
|
78
|
-
"Restart the bot (Maintenance → Restart bot)",
|
|
79
|
-
"The QR code will appear below — scan it with WhatsApp → Linked Devices → Link a Device",
|
|
80
|
-
"The connection is persisted (data/whatsapp-auth/)",
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
id: "slack",
|
|
85
|
-
name: "Slack",
|
|
86
|
-
icon: "💼",
|
|
87
|
-
description: "Slack workspace integration via Socket Mode (no public URL needed). DMs, @mentions in channels, and the `/alvin` slash command for /status, /new, /effort, /help (v4.13.2+).",
|
|
88
|
-
envVars: [
|
|
89
|
-
{ key: "SLACK_BOT_TOKEN", label: "Bot Token (xoxb-...)", placeholder: "xoxb-...", secret: true },
|
|
90
|
-
{ key: "SLACK_APP_TOKEN", label: "App Token (xapp-...)", placeholder: "xapp-...", secret: true },
|
|
91
|
-
],
|
|
92
|
-
npmPackages: ["@slack/bolt"],
|
|
93
|
-
setupUrl: "https://api.slack.com/apps",
|
|
94
|
-
setupSteps: [
|
|
95
|
-
"Go to https://api.slack.com/apps and click 'Create New App' → 'From an app manifest'. Choose your workspace.",
|
|
96
|
-
"Paste the full manifest JSON below into the JSON tab (replaces the template). This sets scopes, events, Messages Tab, Socket Mode, and the /alvin slash command in one go:\n\n{\n \"display_information\": { \"name\": \"Alvin\" },\n \"features\": {\n \"app_home\": {\n \"home_tab_enabled\": false,\n \"messages_tab_enabled\": true,\n \"messages_tab_read_only_enabled\": false\n },\n \"bot_user\": { \"display_name\": \"Alvin\", \"always_online\": false },\n \"slash_commands\": [\n {\n \"command\": \"/alvin\",\n \"description\": \"Alvin bot commands\",\n \"usage_hint\": \"new | status | effort low|medium|high|max | help\",\n \"should_escape\": false\n }\n ]\n },\n \"oauth_config\": {\n \"scopes\": {\n \"bot\": [\n \"app_mentions:read\", \"mpim:read\", \"chat:write\",\n \"channels:history\", \"groups:history\", \"im:history\", \"mpim:history\",\n \"files:write\", \"reactions:write\", \"files:read\",\n \"commands\"\n ]\n },\n \"pkce_enabled\": true\n },\n \"settings\": {\n \"event_subscriptions\": {\n \"bot_events\": [\n \"app_mention\", \"message.channels\", \"message.groups\",\n \"message.im\", \"message.mpim\"\n ]\n },\n \"interactivity\": { \"is_enabled\": true },\n \"org_deploy_enabled\": false,\n \"socket_mode_enabled\": true,\n \"token_rotation_enabled\": false\n }\n}",
|
|
97
|
-
"Click Create. Slack creates the App with all the correct config pre-wired.",
|
|
98
|
-
"Go to Settings → Basic Information → App-Level Tokens → 'Generate Token and Scopes'. Name it 'socket', pick scope 'connections:write', click Generate. Copy the xapp-... token into SLACK_APP_TOKEN below.",
|
|
99
|
-
"Go to Settings → Install App → Install to Workspace → Allow. Copy the 'Bot User OAuth Token' (xoxb-...) into SLACK_BOT_TOKEN below.",
|
|
100
|
-
"Save both tokens here (click 'Save') and then click 'Test Connection' — you should see '@alvin on <Workspace>'.",
|
|
101
|
-
"Click 'Restart bot' in Maintenance → the Slack adapter connects automatically (look for '💬 Slack connected' in the logs).",
|
|
102
|
-
"In Slack: open the app in the sidebar, click 'Messages' tab, send a DM. Or use the slash command: /alvin status, /alvin new, /alvin effort high, /alvin help.",
|
|
103
|
-
"To use in channels: invite the bot with /invite @alvin and then @mention it (e.g. '@alvin what's the weather in Berlin?').",
|
|
104
|
-
],
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
id: "signal",
|
|
108
|
-
name: "Signal",
|
|
109
|
-
icon: "🔒",
|
|
110
|
-
description: "Signal Messenger via signal-cli REST API. Requires a separate signal-cli container.",
|
|
111
|
-
envVars: [
|
|
112
|
-
{ key: "SIGNAL_API_URL", label: "signal-cli REST API URL", placeholder: "http://localhost:8080" },
|
|
113
|
-
{ key: "SIGNAL_NUMBER", label: "Signal Number", placeholder: "+491234567890" },
|
|
114
|
-
],
|
|
115
|
-
setupUrl: "https://github.com/bbernhard/signal-cli-rest-api",
|
|
116
|
-
setupSteps: [
|
|
117
|
-
"Start signal-cli REST API (Docker recommended):",
|
|
118
|
-
"docker run -p 8080:8080 bbernhard/signal-cli-rest-api",
|
|
119
|
-
"Register your number via the API",
|
|
120
|
-
"Enter URL and number above",
|
|
121
|
-
],
|
|
122
|
-
},
|
|
123
|
-
];
|
|
124
|
-
const PROVIDERS = [
|
|
125
|
-
{
|
|
126
|
-
id: "claude-sdk",
|
|
127
|
-
name: "Claude Agent SDK",
|
|
128
|
-
icon: "🟣",
|
|
129
|
-
description: "Full tool use via Agent SDK. Requires Claude CLI login (Max plan or API key).",
|
|
130
|
-
envKey: "",
|
|
131
|
-
models: [
|
|
132
|
-
{ key: "claude-sdk", name: "Claude (Agent SDK)", model: "claude-opus-4-6" },
|
|
133
|
-
],
|
|
134
|
-
signupUrl: "https://console.anthropic.com",
|
|
135
|
-
docsUrl: "https://docs.anthropic.com/en/docs/claude-code",
|
|
136
|
-
setupSteps: [
|
|
137
|
-
"npm install -g @anthropic-ai/claude-code",
|
|
138
|
-
"claude login (browser auth or API key)",
|
|
139
|
-
"Full tool use: read/write files, shell commands, browser",
|
|
140
|
-
],
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
id: "anthropic",
|
|
144
|
-
name: "Anthropic API",
|
|
145
|
-
icon: "🟣",
|
|
146
|
-
description: "Claude Opus, Sonnet, Haiku directly via API key. OpenAI-compatible.",
|
|
147
|
-
envKey: "ANTHROPIC_API_KEY",
|
|
148
|
-
models: [
|
|
149
|
-
{ key: "claude-opus", name: "Claude Opus 4.6", model: "claude-opus-4-6" },
|
|
150
|
-
{ key: "claude-sonnet", name: "Claude Sonnet 4.6", model: "claude-sonnet-4-6" },
|
|
151
|
-
{ key: "claude-haiku", name: "Claude Haiku 4.5", model: "claude-haiku-4-5" },
|
|
152
|
-
],
|
|
153
|
-
signupUrl: "https://console.anthropic.com/settings/keys",
|
|
154
|
-
docsUrl: "https://docs.anthropic.com/en/api",
|
|
155
|
-
setupSteps: [
|
|
156
|
-
"Create account on console.anthropic.com",
|
|
157
|
-
"Generate API key under Settings → API Keys",
|
|
158
|
-
"Add credits (pay-as-you-go) or use subscription",
|
|
159
|
-
],
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
id: "openai",
|
|
163
|
-
name: "OpenAI",
|
|
164
|
-
icon: "🟢",
|
|
165
|
-
description: "GPT-4o, GPT-4.1, o3/o4 and other OpenAI models.",
|
|
166
|
-
envKey: "OPENAI_API_KEY",
|
|
167
|
-
models: [
|
|
168
|
-
{ key: "gpt-4o", name: "GPT-4o", model: "gpt-4o" },
|
|
169
|
-
{ key: "gpt-4o-mini", name: "GPT-4o Mini", model: "gpt-4o-mini" },
|
|
170
|
-
{ key: "gpt-4.1", name: "GPT-4.1", model: "gpt-4.1" },
|
|
171
|
-
{ key: "gpt-4.1-mini", name: "GPT-4.1 Mini", model: "gpt-4.1-mini" },
|
|
172
|
-
{ key: "o3-mini", name: "o3 Mini", model: "o3-mini" },
|
|
173
|
-
],
|
|
174
|
-
signupUrl: "https://platform.openai.com/api-keys",
|
|
175
|
-
docsUrl: "https://platform.openai.com/docs",
|
|
176
|
-
setupSteps: [
|
|
177
|
-
"Create account on platform.openai.com",
|
|
178
|
-
"Generate API key under API Keys",
|
|
179
|
-
"Add credits (pay-as-you-go)",
|
|
180
|
-
],
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
id: "google",
|
|
184
|
-
name: "Google Gemini",
|
|
185
|
-
icon: "🔵",
|
|
186
|
-
description: "Gemini 2.5/3 Pro/Flash via Google AI Studio. Free tier available.",
|
|
187
|
-
envKey: "GOOGLE_API_KEY",
|
|
188
|
-
models: [
|
|
189
|
-
{ key: "gemini-2.5-pro", name: "Gemini 2.5 Pro", model: "gemini-2.5-pro" },
|
|
190
|
-
{ key: "gemini-2.5-flash", name: "Gemini 2.5 Flash", model: "gemini-2.5-flash" },
|
|
191
|
-
{ key: "gemini-3-pro", name: "Gemini 3 Pro (Preview)", model: "gemini-3-pro-preview" },
|
|
192
|
-
{ key: "gemini-3-flash", name: "Gemini 3 Flash (Preview)", model: "gemini-3-flash-preview" },
|
|
193
|
-
],
|
|
194
|
-
signupUrl: "https://aistudio.google.com/apikey",
|
|
195
|
-
docsUrl: "https://ai.google.dev/docs",
|
|
196
|
-
setupSteps: [
|
|
197
|
-
"Open Google AI Studio (aistudio.google.com)",
|
|
198
|
-
"Create API key → ready to use immediately",
|
|
199
|
-
"Free tier: 15 RPM, 1M TPM",
|
|
200
|
-
],
|
|
201
|
-
free: true,
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
id: "nvidia",
|
|
205
|
-
name: "NVIDIA NIM",
|
|
206
|
-
icon: "🟩",
|
|
207
|
-
description: "150+ models free (Llama, Kimi, Mistral, etc.) via NVIDIA API.",
|
|
208
|
-
envKey: "NVIDIA_API_KEY",
|
|
209
|
-
models: [
|
|
210
|
-
{ key: "nvidia-llama-3.3-70b", name: "Llama 3.3 70B", model: "meta/llama-3.3-70b-instruct" },
|
|
211
|
-
{ key: "nvidia-kimi-k2.5", name: "Kimi K2.5", model: "moonshotai/kimi-k2.5" },
|
|
212
|
-
],
|
|
213
|
-
signupUrl: "https://build.nvidia.com",
|
|
214
|
-
docsUrl: "https://docs.api.nvidia.com",
|
|
215
|
-
setupSteps: [
|
|
216
|
-
"Create account on build.nvidia.com",
|
|
217
|
-
"Generate free API key",
|
|
218
|
-
"150+ models available for free (1000 credits/month)",
|
|
219
|
-
],
|
|
220
|
-
free: true,
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
id: "groq",
|
|
224
|
-
name: "Groq",
|
|
225
|
-
icon: "⚡",
|
|
226
|
-
description: "Ultra-fast inference. Llama, Mixtral, Gemma — free and lightning fast.",
|
|
227
|
-
envKey: "GROQ_API_KEY",
|
|
228
|
-
models: [
|
|
229
|
-
{ key: "groq", name: "Llama 3.3 70B (Groq)", model: "llama-3.3-70b-versatile" },
|
|
230
|
-
{ key: "groq-llama-3.1-8b", name: "Llama 3.1 8B (Groq)", model: "llama-3.1-8b-instant" },
|
|
231
|
-
{ key: "groq-mixtral", name: "Mixtral 8x7B (Groq)", model: "mixtral-8x7b-32768" },
|
|
232
|
-
],
|
|
233
|
-
signupUrl: "https://console.groq.com",
|
|
234
|
-
docsUrl: "https://console.groq.com/docs",
|
|
235
|
-
setupSteps: [
|
|
236
|
-
"Create account on console.groq.com (no credit card needed)",
|
|
237
|
-
"Generate API key",
|
|
238
|
-
"Ready to use immediately — free tier with rate limits",
|
|
239
|
-
],
|
|
240
|
-
free: true,
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
id: "openrouter",
|
|
244
|
-
name: "OpenRouter",
|
|
245
|
-
icon: "🌐",
|
|
246
|
-
description: "One API key, 200+ models. Claude, GPT, Gemini, Llama — all via one API.",
|
|
247
|
-
envKey: "OPENROUTER_API_KEY",
|
|
248
|
-
models: [
|
|
249
|
-
{ key: "openrouter", name: "OpenRouter (Standard)", model: "anthropic/claude-sonnet-4" },
|
|
250
|
-
],
|
|
251
|
-
signupUrl: "https://openrouter.ai/keys",
|
|
252
|
-
docsUrl: "https://openrouter.ai/docs",
|
|
253
|
-
setupSteps: [
|
|
254
|
-
"Create account on openrouter.ai",
|
|
255
|
-
"Generate API key",
|
|
256
|
-
"Add credits or use free models",
|
|
257
|
-
],
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
id: "ollama",
|
|
261
|
-
name: "Ollama (Local)",
|
|
262
|
-
icon: "🦙",
|
|
263
|
-
description: "Local models on your machine. No API key needed, runs offline.",
|
|
264
|
-
envKey: "",
|
|
265
|
-
models: [
|
|
266
|
-
{ key: "ollama", name: "Ollama (Local)", model: "llama3.2" },
|
|
267
|
-
],
|
|
268
|
-
signupUrl: "https://ollama.com/download",
|
|
269
|
-
docsUrl: "https://ollama.com/library",
|
|
270
|
-
setupSteps: [
|
|
271
|
-
"Install Ollama: brew install ollama (macOS) or ollama.com/download",
|
|
272
|
-
"Pull a model: ollama pull llama3.2",
|
|
273
|
-
"Runs automatically on localhost:11434",
|
|
274
|
-
],
|
|
275
|
-
free: true,
|
|
276
|
-
},
|
|
277
|
-
];
|
|
278
|
-
// ── API Handler ─────────────────────────────────────────
|
|
279
|
-
export async function handleSetupAPI(req, res, urlPath, body) {
|
|
280
|
-
res.setHeader("Content-Type", "application/json");
|
|
281
|
-
// ── Platforms ───────────────────────────────────────
|
|
282
|
-
// GET /api/platforms/setup — full setup info for all platforms
|
|
283
|
-
if (urlPath === "/api/platforms/setup") {
|
|
284
|
-
const env = readEnv();
|
|
285
|
-
const platforms = PLATFORMS.map(p => ({
|
|
286
|
-
...p,
|
|
287
|
-
configured: (() => {
|
|
288
|
-
// A platform is "configured" if its primary env var(s) are set
|
|
289
|
-
// Toggles: the first toggle being true is enough (e.g., WHATSAPP_ENABLED)
|
|
290
|
-
// Text fields: all non-toggle fields must have a value
|
|
291
|
-
const required = p.envVars.filter(v => v.type !== "toggle");
|
|
292
|
-
const toggles = p.envVars.filter(v => v.type === "toggle");
|
|
293
|
-
if (required.length > 0)
|
|
294
|
-
return required.every(v => !!env[v.key]);
|
|
295
|
-
if (toggles.length > 0)
|
|
296
|
-
return toggles[0] && env[toggles[0].key] === "true";
|
|
297
|
-
return false;
|
|
298
|
-
})(),
|
|
299
|
-
values: Object.fromEntries(p.envVars.map(v => [v.key, v.secret && env[v.key] ? maskSecret(env[v.key]) : (env[v.key] || "")])),
|
|
300
|
-
depsInstalled: p.npmPackages ? checkNpmDeps(p.npmPackages) : true,
|
|
301
|
-
}));
|
|
302
|
-
res.end(JSON.stringify({ platforms }));
|
|
303
|
-
return true;
|
|
304
|
-
}
|
|
305
|
-
// POST /api/platforms/configure — save platform env vars
|
|
306
|
-
if (urlPath === "/api/platforms/configure" && req.method === "POST") {
|
|
307
|
-
try {
|
|
308
|
-
const { platformId, values } = JSON.parse(body);
|
|
309
|
-
const platform = PLATFORMS.find(p => p.id === platformId);
|
|
310
|
-
if (!platform) {
|
|
311
|
-
res.statusCode = 400;
|
|
312
|
-
res.end(JSON.stringify({ error: "Unknown platform" }));
|
|
313
|
-
return true;
|
|
314
|
-
}
|
|
315
|
-
for (const v of platform.envVars) {
|
|
316
|
-
if (values[v.key] !== undefined && values[v.key] !== "") {
|
|
317
|
-
writeEnvVar(v.key, values[v.key]);
|
|
318
|
-
process.env[v.key] = values[v.key]; // Hot-apply for toggle changes
|
|
319
|
-
}
|
|
320
|
-
else if (values[v.key] === "") {
|
|
321
|
-
removeEnvVar(v.key);
|
|
322
|
-
delete process.env[v.key]; // Hot-remove
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
// WhatsApp toggle-only changes (self-chat, groups, DMs) don't need restart
|
|
326
|
-
const onlyToggles = platform.envVars.every(v => v.type === "toggle") ||
|
|
327
|
-
(platformId === "whatsapp" && platform.envVars.filter(v => v.type !== "toggle").every(v => !values[v.key]));
|
|
328
|
-
const restartNeeded = !onlyToggles;
|
|
329
|
-
res.end(JSON.stringify({ ok: true, restartNeeded, note: restartNeeded ? "Restart required to apply changes." : "Saved." }));
|
|
330
|
-
}
|
|
331
|
-
catch {
|
|
332
|
-
res.statusCode = 400;
|
|
333
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
334
|
-
}
|
|
335
|
-
return true;
|
|
336
|
-
}
|
|
337
|
-
// POST /api/platforms/install-deps — install npm packages for a platform
|
|
338
|
-
if (urlPath === "/api/platforms/install-deps" && req.method === "POST") {
|
|
339
|
-
try {
|
|
340
|
-
const { platformId } = JSON.parse(body);
|
|
341
|
-
const platform = PLATFORMS.find(p => p.id === platformId);
|
|
342
|
-
if (!platform?.npmPackages?.length) {
|
|
343
|
-
res.end(JSON.stringify({ ok: true, note: "No dependencies needed." }));
|
|
344
|
-
return true;
|
|
345
|
-
}
|
|
346
|
-
const pkgs = platform.npmPackages.join(" ");
|
|
347
|
-
const output = execSync(`cd "${BOT_ROOT}" && npm install ${pkgs} --save-optional 2>&1`, {
|
|
348
|
-
timeout: 120000,
|
|
349
|
-
env: { ...process.env, PATH: process.env.PATH + ":/opt/homebrew/bin:/usr/local/bin" },
|
|
350
|
-
}).toString();
|
|
351
|
-
res.end(JSON.stringify({ ok: true, output: output.slice(0, 5000) }));
|
|
352
|
-
}
|
|
353
|
-
catch (err) {
|
|
354
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
355
|
-
res.end(JSON.stringify({ error }));
|
|
356
|
-
}
|
|
357
|
-
return true;
|
|
358
|
-
}
|
|
359
|
-
// ── Models / Providers ─────────────────────────────
|
|
360
|
-
// GET /api/providers/setup — full setup info for all providers
|
|
361
|
-
if (urlPath === "/api/providers/setup") {
|
|
362
|
-
const env = readEnv();
|
|
363
|
-
const registry = getRegistry();
|
|
364
|
-
const activeKey = registry.getActiveKey();
|
|
365
|
-
const registeredModels = await registry.listAll();
|
|
366
|
-
const providers = PROVIDERS.map(p => ({
|
|
367
|
-
...p,
|
|
368
|
-
hasKey: p.envKey ? !!env[p.envKey] : true, // Ollama doesn't need key
|
|
369
|
-
keyPreview: p.envKey && env[p.envKey] ? maskSecret(env[p.envKey]) : "",
|
|
370
|
-
modelsActive: p.models.map(m => ({
|
|
371
|
-
...m,
|
|
372
|
-
registered: registeredModels.some(rm => rm.key === m.key),
|
|
373
|
-
active: activeKey === m.key,
|
|
374
|
-
status: registeredModels.find(rm => rm.key === m.key)?.status || "not configured",
|
|
375
|
-
})),
|
|
376
|
-
}));
|
|
377
|
-
const customModels = loadCustomModels();
|
|
378
|
-
res.end(JSON.stringify({ providers, customModels, activeModel: activeKey }));
|
|
379
|
-
return true;
|
|
380
|
-
}
|
|
381
|
-
// POST /api/providers/set-key — save an API key
|
|
382
|
-
if (urlPath === "/api/providers/set-key" && req.method === "POST") {
|
|
383
|
-
try {
|
|
384
|
-
const { providerId, apiKey } = JSON.parse(body);
|
|
385
|
-
const provider = PROVIDERS.find(p => p.id === providerId);
|
|
386
|
-
if (!provider?.envKey) {
|
|
387
|
-
res.statusCode = 400;
|
|
388
|
-
res.end(JSON.stringify({ error: "Provider does not need an API key" }));
|
|
389
|
-
return true;
|
|
390
|
-
}
|
|
391
|
-
writeEnvVar(provider.envKey, apiKey);
|
|
392
|
-
res.end(JSON.stringify({ ok: true, note: "Restart required to activate the new key." }));
|
|
393
|
-
}
|
|
394
|
-
catch {
|
|
395
|
-
res.statusCode = 400;
|
|
396
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
397
|
-
}
|
|
398
|
-
return true;
|
|
399
|
-
}
|
|
400
|
-
// POST /api/providers/set-primary — set primary provider
|
|
401
|
-
if (urlPath === "/api/providers/set-primary" && req.method === "POST") {
|
|
402
|
-
try {
|
|
403
|
-
const { key } = JSON.parse(body);
|
|
404
|
-
writeEnvVar("PRIMARY_PROVIDER", key);
|
|
405
|
-
// Also switch runtime
|
|
406
|
-
const registry = getRegistry();
|
|
407
|
-
registry.switchTo(key);
|
|
408
|
-
res.end(JSON.stringify({ ok: true }));
|
|
409
|
-
}
|
|
410
|
-
catch {
|
|
411
|
-
res.statusCode = 400;
|
|
412
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
413
|
-
}
|
|
414
|
-
return true;
|
|
415
|
-
}
|
|
416
|
-
// POST /api/providers/set-fallbacks — set fallback chain
|
|
417
|
-
if (urlPath === "/api/providers/set-fallbacks" && req.method === "POST") {
|
|
418
|
-
try {
|
|
419
|
-
const { keys } = JSON.parse(body);
|
|
420
|
-
writeEnvVar("FALLBACK_PROVIDERS", keys.join(","));
|
|
421
|
-
res.end(JSON.stringify({ ok: true, note: "Restart required." }));
|
|
422
|
-
}
|
|
423
|
-
catch {
|
|
424
|
-
res.statusCode = 400;
|
|
425
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
426
|
-
}
|
|
427
|
-
return true;
|
|
428
|
-
}
|
|
429
|
-
// GET /api/providers/live-models?id=<providerId> — fetch available models from provider API
|
|
430
|
-
if (urlPath?.startsWith("/api/providers/live-models") && req.method === "GET") {
|
|
431
|
-
try {
|
|
432
|
-
const url = new URL(req.url || "", `http://${req.headers.host}`);
|
|
433
|
-
const providerId = url.searchParams.get("id") || "";
|
|
434
|
-
const models = await fetchLiveModels(providerId);
|
|
435
|
-
res.end(JSON.stringify({ ok: true, providerId, models }));
|
|
436
|
-
}
|
|
437
|
-
catch (err) {
|
|
438
|
-
res.end(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err), models: [] }));
|
|
439
|
-
}
|
|
440
|
-
return true;
|
|
441
|
-
}
|
|
442
|
-
// POST /api/providers/add-custom — add a custom model
|
|
443
|
-
if (urlPath === "/api/providers/add-custom" && req.method === "POST") {
|
|
444
|
-
try {
|
|
445
|
-
const model = JSON.parse(body);
|
|
446
|
-
if (!model.key || !model.name || !model.baseUrl || !model.model) {
|
|
447
|
-
res.statusCode = 400;
|
|
448
|
-
res.end(JSON.stringify({ error: "key, name, baseUrl and model are required fields" }));
|
|
449
|
-
return true;
|
|
450
|
-
}
|
|
451
|
-
model.type = "openai-compatible";
|
|
452
|
-
const models = loadCustomModels();
|
|
453
|
-
// Upsert
|
|
454
|
-
const idx = models.findIndex(m => m.key === model.key);
|
|
455
|
-
if (idx >= 0)
|
|
456
|
-
models[idx] = model;
|
|
457
|
-
else
|
|
458
|
-
models.push(model);
|
|
459
|
-
saveCustomModels(models);
|
|
460
|
-
// Save API key if provided
|
|
461
|
-
if (model.apiKeyEnv && model.apiKey) {
|
|
462
|
-
writeEnvVar(model.apiKeyEnv, model.apiKey);
|
|
463
|
-
}
|
|
464
|
-
res.end(JSON.stringify({ ok: true, note: "Restart required to activate the model." }));
|
|
465
|
-
}
|
|
466
|
-
catch {
|
|
467
|
-
res.statusCode = 400;
|
|
468
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
469
|
-
}
|
|
470
|
-
return true;
|
|
471
|
-
}
|
|
472
|
-
// DELETE /api/providers/remove-custom — remove a custom model
|
|
473
|
-
if (urlPath === "/api/providers/remove-custom" && req.method === "POST") {
|
|
474
|
-
try {
|
|
475
|
-
const { key } = JSON.parse(body);
|
|
476
|
-
const models = loadCustomModels().filter(m => m.key !== key);
|
|
477
|
-
saveCustomModels(models);
|
|
478
|
-
res.end(JSON.stringify({ ok: true }));
|
|
479
|
-
}
|
|
480
|
-
catch {
|
|
481
|
-
res.statusCode = 400;
|
|
482
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
483
|
-
}
|
|
484
|
-
return true;
|
|
485
|
-
}
|
|
486
|
-
// POST /api/providers/test-key — quick API key validation
|
|
487
|
-
if (urlPath === "/api/providers/test-key" && req.method === "POST") {
|
|
488
|
-
try {
|
|
489
|
-
const { providerId, apiKey } = JSON.parse(body);
|
|
490
|
-
const result = await testApiKey(providerId, apiKey);
|
|
491
|
-
res.end(JSON.stringify(result));
|
|
492
|
-
}
|
|
493
|
-
catch (err) {
|
|
494
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
495
|
-
res.end(JSON.stringify({ ok: false, error }));
|
|
496
|
-
}
|
|
497
|
-
return true;
|
|
498
|
-
}
|
|
499
|
-
// ── Sudo / Elevated Access ─────────────────────────
|
|
500
|
-
// GET /api/sudo/status — check sudo configuration
|
|
501
|
-
if (urlPath === "/api/sudo/status") {
|
|
502
|
-
const status = await getSudoStatus();
|
|
503
|
-
res.end(JSON.stringify(status));
|
|
504
|
-
return true;
|
|
505
|
-
}
|
|
506
|
-
// POST /api/sudo/setup — store sudo password
|
|
507
|
-
if (urlPath === "/api/sudo/setup" && req.method === "POST") {
|
|
508
|
-
try {
|
|
509
|
-
const { password } = JSON.parse(body);
|
|
510
|
-
if (!password) {
|
|
511
|
-
res.statusCode = 400;
|
|
512
|
-
res.end(JSON.stringify({ error: "Password required" }));
|
|
513
|
-
return true;
|
|
514
|
-
}
|
|
515
|
-
const result = storePassword(password);
|
|
516
|
-
if (result.ok) {
|
|
517
|
-
// Verify it works
|
|
518
|
-
const verify = await verifyPassword();
|
|
519
|
-
if (verify.ok) {
|
|
520
|
-
res.end(JSON.stringify({ ok: true, method: result.method, verified: true }));
|
|
521
|
-
}
|
|
522
|
-
else {
|
|
523
|
-
revokePassword(); // Clean up if wrong password
|
|
524
|
-
res.end(JSON.stringify({ ok: false, error: "Password stored but verification failed: " + verify.error }));
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
res.end(JSON.stringify({ ok: false, error: result.error }));
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
catch {
|
|
532
|
-
res.statusCode = 400;
|
|
533
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
534
|
-
}
|
|
535
|
-
return true;
|
|
536
|
-
}
|
|
537
|
-
// POST /api/sudo/revoke — delete stored password
|
|
538
|
-
if (urlPath === "/api/sudo/revoke" && req.method === "POST") {
|
|
539
|
-
const ok = revokePassword();
|
|
540
|
-
res.end(JSON.stringify({ ok }));
|
|
541
|
-
return true;
|
|
542
|
-
}
|
|
543
|
-
// POST /api/sudo/verify — test if stored password works
|
|
544
|
-
if (urlPath === "/api/sudo/verify" && req.method === "POST") {
|
|
545
|
-
const result = await verifyPassword();
|
|
546
|
-
res.end(JSON.stringify(result));
|
|
547
|
-
return true;
|
|
548
|
-
}
|
|
549
|
-
// POST /api/sudo/exec — execute a command with sudo
|
|
550
|
-
if (urlPath === "/api/sudo/exec" && req.method === "POST") {
|
|
551
|
-
try {
|
|
552
|
-
const { command } = JSON.parse(body);
|
|
553
|
-
if (!command) {
|
|
554
|
-
res.statusCode = 400;
|
|
555
|
-
res.end(JSON.stringify({ error: "No command specified" }));
|
|
556
|
-
return true;
|
|
557
|
-
}
|
|
558
|
-
const result = await sudoExec(command);
|
|
559
|
-
res.end(JSON.stringify(result));
|
|
560
|
-
}
|
|
561
|
-
catch {
|
|
562
|
-
res.statusCode = 400;
|
|
563
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
564
|
-
}
|
|
565
|
-
return true;
|
|
566
|
-
}
|
|
567
|
-
// POST /api/sudo/admin-dialog — show macOS admin dialog
|
|
568
|
-
if (urlPath === "/api/sudo/admin-dialog" && req.method === "POST") {
|
|
569
|
-
try {
|
|
570
|
-
const { reason } = JSON.parse(body);
|
|
571
|
-
const result = await requestAdminViaDialog(reason || "Alvin Bot requires administrator privileges");
|
|
572
|
-
res.end(JSON.stringify(result));
|
|
573
|
-
}
|
|
574
|
-
catch {
|
|
575
|
-
res.statusCode = 400;
|
|
576
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
577
|
-
}
|
|
578
|
-
return true;
|
|
579
|
-
}
|
|
580
|
-
// POST /api/sudo/open-settings — open macOS system settings
|
|
581
|
-
if (urlPath === "/api/sudo/open-settings" && req.method === "POST") {
|
|
582
|
-
try {
|
|
583
|
-
const { pane } = JSON.parse(body);
|
|
584
|
-
const ok = openSystemSettings(pane || "security");
|
|
585
|
-
res.end(JSON.stringify({ ok }));
|
|
586
|
-
}
|
|
587
|
-
catch {
|
|
588
|
-
res.statusCode = 400;
|
|
589
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
590
|
-
}
|
|
591
|
-
return true;
|
|
592
|
-
}
|
|
593
|
-
// ── Skills ────────────────────────────────────────────
|
|
594
|
-
// GET /api/skills — list all loaded skills
|
|
595
|
-
if (urlPath === "/api/skills") {
|
|
596
|
-
const { getSkills } = await import("../services/skills.js");
|
|
597
|
-
const skills = getSkills().map(s => ({
|
|
598
|
-
id: s.id,
|
|
599
|
-
name: s.name,
|
|
600
|
-
description: s.description,
|
|
601
|
-
triggers: s.triggers,
|
|
602
|
-
priority: s.priority,
|
|
603
|
-
category: s.category,
|
|
604
|
-
}));
|
|
605
|
-
res.end(JSON.stringify({ skills }));
|
|
606
|
-
return true;
|
|
607
|
-
}
|
|
608
|
-
// ── Cron Jobs ───────────────────────────────────────
|
|
609
|
-
// GET /api/cron — list all jobs
|
|
610
|
-
if (urlPath === "/api/cron") {
|
|
611
|
-
const jobs = listJobs();
|
|
612
|
-
const enriched = jobs.map(j => ({
|
|
613
|
-
...j,
|
|
614
|
-
nextRunFormatted: formatNextRun(j.nextRunAt),
|
|
615
|
-
lastRunFormatted: j.lastRunAt ? new Date(j.lastRunAt).toLocaleString("de-DE") : null,
|
|
616
|
-
scheduleReadable: humanReadableSchedule(j.schedule),
|
|
617
|
-
}));
|
|
618
|
-
res.end(JSON.stringify({ jobs: enriched }));
|
|
619
|
-
return true;
|
|
620
|
-
}
|
|
621
|
-
// POST /api/cron/create — create a new job
|
|
622
|
-
if (urlPath === "/api/cron/create" && req.method === "POST") {
|
|
623
|
-
try {
|
|
624
|
-
const data = JSON.parse(body);
|
|
625
|
-
const job = createJob({
|
|
626
|
-
name: data.name,
|
|
627
|
-
type: data.type,
|
|
628
|
-
schedule: data.schedule,
|
|
629
|
-
oneShot: data.oneShot || false,
|
|
630
|
-
payload: data.payload || {},
|
|
631
|
-
target: data.target || { platform: "web", chatId: "dashboard" },
|
|
632
|
-
createdBy: "web-ui",
|
|
633
|
-
});
|
|
634
|
-
res.end(JSON.stringify({ ok: true, job }));
|
|
635
|
-
}
|
|
636
|
-
catch (err) {
|
|
637
|
-
res.statusCode = 400;
|
|
638
|
-
const error = err instanceof Error ? err.message : "Invalid request";
|
|
639
|
-
res.end(JSON.stringify({ error }));
|
|
640
|
-
}
|
|
641
|
-
return true;
|
|
642
|
-
}
|
|
643
|
-
// POST /api/cron/delete — delete a job
|
|
644
|
-
if (urlPath === "/api/cron/delete" && req.method === "POST") {
|
|
645
|
-
try {
|
|
646
|
-
const { id } = JSON.parse(body);
|
|
647
|
-
const ok = deleteJob(id);
|
|
648
|
-
res.end(JSON.stringify({ ok }));
|
|
649
|
-
}
|
|
650
|
-
catch {
|
|
651
|
-
res.statusCode = 400;
|
|
652
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
653
|
-
}
|
|
654
|
-
return true;
|
|
655
|
-
}
|
|
656
|
-
// POST /api/cron/update — update job fields (schedule, name, oneShot)
|
|
657
|
-
if (urlPath === "/api/cron/update" && req.method === "POST") {
|
|
658
|
-
try {
|
|
659
|
-
const { id, ...updates } = JSON.parse(body);
|
|
660
|
-
if (!id) {
|
|
661
|
-
res.statusCode = 400;
|
|
662
|
-
res.end(JSON.stringify({ error: "id required" }));
|
|
663
|
-
return true;
|
|
664
|
-
}
|
|
665
|
-
// Only allow safe fields
|
|
666
|
-
const allowed = {};
|
|
667
|
-
if (updates.schedule !== undefined)
|
|
668
|
-
allowed.schedule = updates.schedule;
|
|
669
|
-
if (updates.name !== undefined)
|
|
670
|
-
allowed.name = updates.name;
|
|
671
|
-
if (updates.oneShot !== undefined)
|
|
672
|
-
allowed.oneShot = updates.oneShot;
|
|
673
|
-
const job = updateJob(id, allowed);
|
|
674
|
-
if (!job) {
|
|
675
|
-
res.statusCode = 404;
|
|
676
|
-
res.end(JSON.stringify({ error: "Job not found" }));
|
|
677
|
-
return true;
|
|
678
|
-
}
|
|
679
|
-
res.end(JSON.stringify({ ok: true, job }));
|
|
680
|
-
}
|
|
681
|
-
catch (err) {
|
|
682
|
-
res.statusCode = 400;
|
|
683
|
-
const error = err instanceof Error ? err.message : "Invalid request";
|
|
684
|
-
res.end(JSON.stringify({ error }));
|
|
685
|
-
}
|
|
686
|
-
return true;
|
|
687
|
-
}
|
|
688
|
-
// POST /api/cron/toggle — enable/disable a job
|
|
689
|
-
if (urlPath === "/api/cron/toggle" && req.method === "POST") {
|
|
690
|
-
try {
|
|
691
|
-
const { id } = JSON.parse(body);
|
|
692
|
-
const job = toggleJob(id);
|
|
693
|
-
res.end(JSON.stringify({ ok: !!job, job }));
|
|
694
|
-
}
|
|
695
|
-
catch {
|
|
696
|
-
res.statusCode = 400;
|
|
697
|
-
res.end(JSON.stringify({ error: "Invalid request" }));
|
|
698
|
-
}
|
|
699
|
-
return true;
|
|
700
|
-
}
|
|
701
|
-
// POST /api/cron/run — run a job immediately
|
|
702
|
-
if (urlPath === "/api/cron/run" && req.method === "POST") {
|
|
703
|
-
try {
|
|
704
|
-
const { id } = JSON.parse(body);
|
|
705
|
-
const result = await (runJobNow(id) || Promise.resolve({ output: "", error: "Job not found" }));
|
|
706
|
-
res.end(JSON.stringify(result));
|
|
707
|
-
}
|
|
708
|
-
catch (err) {
|
|
709
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
710
|
-
res.end(JSON.stringify({ error }));
|
|
711
|
-
}
|
|
712
|
-
return true;
|
|
713
|
-
}
|
|
714
|
-
// ── Platform Connection Status ─────────────────────────
|
|
715
|
-
// GET /api/platforms/status — live connection status for all platforms
|
|
716
|
-
if (urlPath === "/api/platforms/status") {
|
|
717
|
-
const statuses = {};
|
|
718
|
-
// Telegram
|
|
719
|
-
try {
|
|
720
|
-
const { getTelegramState } = await import("../platforms/telegram.js");
|
|
721
|
-
statuses.telegram = getTelegramState();
|
|
722
|
-
}
|
|
723
|
-
catch {
|
|
724
|
-
statuses.telegram = { status: !!process.env.BOT_TOKEN ? "unknown" : "not_configured" };
|
|
725
|
-
}
|
|
726
|
-
// Discord
|
|
727
|
-
try {
|
|
728
|
-
const { getDiscordState } = await import("../platforms/discord.js");
|
|
729
|
-
statuses.discord = getDiscordState();
|
|
730
|
-
}
|
|
731
|
-
catch {
|
|
732
|
-
statuses.discord = { status: !!process.env.DISCORD_TOKEN ? "unknown" : "not_configured" };
|
|
733
|
-
}
|
|
734
|
-
// WhatsApp
|
|
735
|
-
try {
|
|
736
|
-
const { getWhatsAppState } = await import("../platforms/whatsapp.js");
|
|
737
|
-
statuses.whatsapp = getWhatsAppState();
|
|
738
|
-
}
|
|
739
|
-
catch {
|
|
740
|
-
statuses.whatsapp = { status: process.env.WHATSAPP_ENABLED === "true" ? "unknown" : "not_configured" };
|
|
741
|
-
}
|
|
742
|
-
// Signal
|
|
743
|
-
try {
|
|
744
|
-
const { getSignalState } = await import("../platforms/signal.js");
|
|
745
|
-
statuses.signal = getSignalState();
|
|
746
|
-
}
|
|
747
|
-
catch {
|
|
748
|
-
statuses.signal = { status: !!process.env.SIGNAL_API_URL ? "unknown" : "not_configured" };
|
|
749
|
-
}
|
|
750
|
-
res.end(JSON.stringify(statuses));
|
|
751
|
-
return true;
|
|
752
|
-
}
|
|
753
|
-
// GET /api/whatsapp/status — WhatsApp-specific (QR code needs its own endpoint)
|
|
754
|
-
if (urlPath === "/api/whatsapp/status") {
|
|
755
|
-
try {
|
|
756
|
-
const { getWhatsAppState } = await import("../platforms/whatsapp.js");
|
|
757
|
-
const state = getWhatsAppState();
|
|
758
|
-
res.end(JSON.stringify(state));
|
|
759
|
-
}
|
|
760
|
-
catch {
|
|
761
|
-
res.end(JSON.stringify({ status: "disconnected", qrString: null, error: "WhatsApp adapter not loaded" }));
|
|
762
|
-
}
|
|
763
|
-
return true;
|
|
764
|
-
}
|
|
765
|
-
// POST /api/whatsapp/disconnect — clear auth and disconnect
|
|
766
|
-
if (urlPath === "/api/whatsapp/disconnect" && req.method === "POST") {
|
|
767
|
-
try {
|
|
768
|
-
const authDir = WHATSAPP_AUTH;
|
|
769
|
-
if (fs.existsSync(authDir)) {
|
|
770
|
-
fs.rmSync(authDir, { recursive: true });
|
|
771
|
-
}
|
|
772
|
-
res.end(JSON.stringify({ ok: true, note: "Auth data cleared. Restart required for new connection." }));
|
|
773
|
-
}
|
|
774
|
-
catch (err) {
|
|
775
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
776
|
-
res.end(JSON.stringify({ ok: false, error }));
|
|
777
|
-
}
|
|
778
|
-
return true;
|
|
779
|
-
}
|
|
780
|
-
// POST /api/platforms/test-connection — test a specific platform
|
|
781
|
-
if (urlPath === "/api/platforms/test-connection" && req.method === "POST") {
|
|
782
|
-
try {
|
|
783
|
-
const { platformId } = JSON.parse(body);
|
|
784
|
-
if (platformId === "telegram") {
|
|
785
|
-
const token = process.env.BOT_TOKEN;
|
|
786
|
-
if (!token) {
|
|
787
|
-
res.end(JSON.stringify({ ok: false, error: "BOT_TOKEN not set" }));
|
|
788
|
-
return true;
|
|
789
|
-
}
|
|
790
|
-
const apiRes = await fetch(`https://api.telegram.org/bot${token}/getMe`);
|
|
791
|
-
const data = await apiRes.json();
|
|
792
|
-
if (data.ok) {
|
|
793
|
-
res.end(JSON.stringify({ ok: true, info: `@${data.result.username} (${data.result.first_name})` }));
|
|
794
|
-
}
|
|
795
|
-
else {
|
|
796
|
-
res.end(JSON.stringify({ ok: false, error: data.description || "Invalid token" }));
|
|
797
|
-
}
|
|
798
|
-
return true;
|
|
799
|
-
}
|
|
800
|
-
if (platformId === "discord") {
|
|
801
|
-
const token = process.env.DISCORD_TOKEN;
|
|
802
|
-
if (!token) {
|
|
803
|
-
res.end(JSON.stringify({ ok: false, error: "DISCORD_TOKEN not set" }));
|
|
804
|
-
return true;
|
|
805
|
-
}
|
|
806
|
-
const apiRes = await fetch("https://discord.com/api/v10/users/@me", {
|
|
807
|
-
headers: { Authorization: `Bot ${token}` },
|
|
808
|
-
});
|
|
809
|
-
const data = await apiRes.json();
|
|
810
|
-
if (data.id) {
|
|
811
|
-
res.end(JSON.stringify({ ok: true, info: `${data.username}#${data.discriminator || '0'} (ID: ${data.id})` }));
|
|
812
|
-
}
|
|
813
|
-
else {
|
|
814
|
-
res.end(JSON.stringify({ ok: false, error: data.message || "Invalid token" }));
|
|
815
|
-
}
|
|
816
|
-
return true;
|
|
817
|
-
}
|
|
818
|
-
if (platformId === "signal") {
|
|
819
|
-
const apiUrl = process.env.SIGNAL_API_URL;
|
|
820
|
-
if (!apiUrl) {
|
|
821
|
-
res.end(JSON.stringify({ ok: false, error: "SIGNAL_API_URL not set" }));
|
|
822
|
-
return true;
|
|
823
|
-
}
|
|
824
|
-
const apiRes = await fetch(`${apiUrl.replace(/\/$/, '')}/v1/about`);
|
|
825
|
-
if (apiRes.ok) {
|
|
826
|
-
const data = await apiRes.json();
|
|
827
|
-
res.end(JSON.stringify({ ok: true, info: `signal-cli API v${data.version || '?'} reachable` }));
|
|
828
|
-
}
|
|
829
|
-
else {
|
|
830
|
-
res.end(JSON.stringify({ ok: false, error: `API responded with ${apiRes.status}` }));
|
|
831
|
-
}
|
|
832
|
-
return true;
|
|
833
|
-
}
|
|
834
|
-
if (platformId === "whatsapp") {
|
|
835
|
-
try {
|
|
836
|
-
const { getWhatsAppState } = await import("../platforms/whatsapp.js");
|
|
837
|
-
const state = getWhatsAppState();
|
|
838
|
-
res.end(JSON.stringify({ ok: state.status === "connected", info: `Status: ${state.status}` }));
|
|
839
|
-
}
|
|
840
|
-
catch {
|
|
841
|
-
res.end(JSON.stringify({ ok: false, error: "WhatsApp adapter not loaded" }));
|
|
842
|
-
}
|
|
843
|
-
return true;
|
|
844
|
-
}
|
|
845
|
-
if (platformId === "slack") {
|
|
846
|
-
// v4.13.1 — Validate Slack config via auth.test (Bot Token) +
|
|
847
|
-
// format check on App Token (xapp-). We can't actually "ping"
|
|
848
|
-
// Socket Mode without opening a WebSocket, so we rely on the
|
|
849
|
-
// App Token prefix as the cheapest sanity check.
|
|
850
|
-
const botToken = process.env.SLACK_BOT_TOKEN;
|
|
851
|
-
const appToken = process.env.SLACK_APP_TOKEN;
|
|
852
|
-
if (!botToken) {
|
|
853
|
-
res.end(JSON.stringify({ ok: false, error: "SLACK_BOT_TOKEN not set" }));
|
|
854
|
-
return true;
|
|
855
|
-
}
|
|
856
|
-
try {
|
|
857
|
-
const apiRes = await fetch("https://slack.com/api/auth.test", {
|
|
858
|
-
method: "POST",
|
|
859
|
-
headers: {
|
|
860
|
-
"Authorization": `Bearer ${botToken}`,
|
|
861
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
862
|
-
},
|
|
863
|
-
});
|
|
864
|
-
const data = await apiRes.json();
|
|
865
|
-
if (!data.ok) {
|
|
866
|
-
res.end(JSON.stringify({
|
|
867
|
-
ok: false,
|
|
868
|
-
error: `Slack rejected Bot Token: ${data.error || "unknown error"}`,
|
|
869
|
-
}));
|
|
870
|
-
return true;
|
|
871
|
-
}
|
|
872
|
-
// Bot Token valid. Now check App Token format — Socket Mode
|
|
873
|
-
// requires it and the xapp- prefix is the quickest sanity check.
|
|
874
|
-
let warning = "";
|
|
875
|
-
if (!appToken) {
|
|
876
|
-
warning = " ⚠️ SLACK_APP_TOKEN not set — Socket Mode will fail.";
|
|
877
|
-
}
|
|
878
|
-
else if (!appToken.startsWith("xapp-")) {
|
|
879
|
-
warning =
|
|
880
|
-
" ⚠️ SLACK_APP_TOKEN has wrong prefix (expected xapp-) — Socket Mode will fail.";
|
|
881
|
-
}
|
|
882
|
-
res.end(JSON.stringify({
|
|
883
|
-
ok: true,
|
|
884
|
-
info: `@${data.user} on ${data.team} (team_id: ${data.team_id}, bot_id: ${data.bot_id})` +
|
|
885
|
-
warning,
|
|
886
|
-
}));
|
|
887
|
-
}
|
|
888
|
-
catch (err) {
|
|
889
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
890
|
-
res.end(JSON.stringify({
|
|
891
|
-
ok: false,
|
|
892
|
-
error: `Failed to reach slack.com/api/auth.test: ${msg}`,
|
|
893
|
-
}));
|
|
894
|
-
}
|
|
895
|
-
return true;
|
|
896
|
-
}
|
|
897
|
-
res.end(JSON.stringify({ ok: false, error: "Unknown platform" }));
|
|
898
|
-
}
|
|
899
|
-
catch (err) {
|
|
900
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
901
|
-
res.end(JSON.stringify({ ok: false, error }));
|
|
902
|
-
}
|
|
903
|
-
return true;
|
|
904
|
-
}
|
|
905
|
-
return false; // Not handled
|
|
906
|
-
}
|
|
907
|
-
// ── Helpers ─────────────────────────────────────────────
|
|
908
|
-
function maskSecret(value) {
|
|
909
|
-
if (value.length <= 8)
|
|
910
|
-
return "****";
|
|
911
|
-
return value.slice(0, 4) + "..." + value.slice(-4);
|
|
912
|
-
}
|
|
913
|
-
function checkNpmDeps(packages) {
|
|
914
|
-
const nodeModules = resolve(BOT_ROOT, "node_modules");
|
|
915
|
-
return packages.every(pkg => {
|
|
916
|
-
try {
|
|
917
|
-
return fs.existsSync(resolve(nodeModules, pkg.split("/")[0]));
|
|
918
|
-
}
|
|
919
|
-
catch {
|
|
920
|
-
return false;
|
|
921
|
-
}
|
|
922
|
-
});
|
|
923
|
-
}
|
|
924
|
-
async function testApiKey(providerId, apiKey) {
|
|
925
|
-
try {
|
|
926
|
-
const provider = PROVIDERS.find(p => p.id === providerId);
|
|
927
|
-
if (!provider)
|
|
928
|
-
return { ok: false, error: "Unknown provider" };
|
|
929
|
-
// Use stored key if requested (input was empty but key already configured)
|
|
930
|
-
// Skip for providers that don't use API keys (e.g. claude-sdk uses CLI auth)
|
|
931
|
-
if (apiKey === "__USE_STORED__") {
|
|
932
|
-
if (providerId === "claude-sdk" || providerId === "ollama") {
|
|
933
|
-
apiKey = ""; // These don't need keys — test will check CLI/service availability
|
|
934
|
-
}
|
|
935
|
-
else {
|
|
936
|
-
const envKey = provider.envKey;
|
|
937
|
-
const storedKey = envKey ? process.env[envKey] : undefined;
|
|
938
|
-
if (!storedKey)
|
|
939
|
-
return { ok: false, error: "No stored key available" };
|
|
940
|
-
apiKey = storedKey;
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
switch (providerId) {
|
|
944
|
-
case "openai": {
|
|
945
|
-
const r = await fetch("https://api.openai.com/v1/models", { headers: { Authorization: `Bearer ${apiKey}` } });
|
|
946
|
-
if (!r.ok)
|
|
947
|
-
return { ok: false, error: `HTTP ${r.status}: ${await r.text()}` };
|
|
948
|
-
return { ok: true, model: "gpt-4o" };
|
|
949
|
-
}
|
|
950
|
-
case "google": {
|
|
951
|
-
const r = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`);
|
|
952
|
-
if (!r.ok)
|
|
953
|
-
return { ok: false, error: `HTTP ${r.status}: ${await r.text()}` };
|
|
954
|
-
return { ok: true, model: "gemini-2.5-pro" };
|
|
955
|
-
}
|
|
956
|
-
case "nvidia": {
|
|
957
|
-
const r = await fetch("https://integrate.api.nvidia.com/v1/models", { headers: { Authorization: `Bearer ${apiKey}` } });
|
|
958
|
-
if (!r.ok)
|
|
959
|
-
return { ok: false, error: `HTTP ${r.status}: ${await r.text()}` };
|
|
960
|
-
return { ok: true, model: "meta/llama-3.3-70b-instruct" };
|
|
961
|
-
}
|
|
962
|
-
case "openrouter": {
|
|
963
|
-
const r = await fetch("https://openrouter.ai/api/v1/models", { headers: { Authorization: `Bearer ${apiKey}` } });
|
|
964
|
-
if (!r.ok)
|
|
965
|
-
return { ok: false, error: `HTTP ${r.status}: ${await r.text()}` };
|
|
966
|
-
return { ok: true, model: "anthropic/claude-sonnet-4" };
|
|
967
|
-
}
|
|
968
|
-
case "groq": {
|
|
969
|
-
const r = await fetch("https://api.groq.com/openai/v1/models", { headers: { Authorization: `Bearer ${apiKey}` } });
|
|
970
|
-
if (!r.ok)
|
|
971
|
-
return { ok: false, error: `HTTP ${r.status}: ${await r.text()}` };
|
|
972
|
-
return { ok: true, model: "llama-3.3-70b-versatile" };
|
|
973
|
-
}
|
|
974
|
-
case "claude-sdk": {
|
|
975
|
-
// Claude SDK uses CLI auth, not an API key — check if CLI is available
|
|
976
|
-
const { execSync } = await import("child_process");
|
|
977
|
-
try {
|
|
978
|
-
execSync("claude --version", { timeout: 5000, stdio: "pipe" });
|
|
979
|
-
return { ok: true, model: "claude-opus-4-6" };
|
|
980
|
-
}
|
|
981
|
-
catch {
|
|
982
|
-
return { ok: false, error: "Claude CLI not installed or not logged in" };
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
case "anthropic": {
|
|
986
|
-
// Anthropic API via OpenAI-compatible endpoint
|
|
987
|
-
const r = await fetch("https://api.anthropic.com/v1/models", {
|
|
988
|
-
headers: { "x-api-key": apiKey, "anthropic-version": "2023-06-01" },
|
|
989
|
-
});
|
|
990
|
-
if (!r.ok)
|
|
991
|
-
return { ok: false, error: `HTTP ${r.status}: ${(await r.text()).substring(0, 200)}` };
|
|
992
|
-
return { ok: true, model: "claude-sonnet-4" };
|
|
993
|
-
}
|
|
994
|
-
default:
|
|
995
|
-
return { ok: false, error: "Key test not available for this provider" };
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
catch (err) {
|
|
999
|
-
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
async function fetchLiveModels(providerId) {
|
|
1003
|
-
const env = process.env;
|
|
1004
|
-
switch (providerId) {
|
|
1005
|
-
case "anthropic": {
|
|
1006
|
-
const key = env.ANTHROPIC_API_KEY;
|
|
1007
|
-
if (!key)
|
|
1008
|
-
return [];
|
|
1009
|
-
const r = await fetch("https://api.anthropic.com/v1/models", {
|
|
1010
|
-
headers: { "x-api-key": key, "anthropic-version": "2023-06-01" },
|
|
1011
|
-
});
|
|
1012
|
-
if (!r.ok)
|
|
1013
|
-
return [];
|
|
1014
|
-
const data = await r.json();
|
|
1015
|
-
return (data.data || [])
|
|
1016
|
-
.filter((m) => m.id && !m.id.includes("pdfs"))
|
|
1017
|
-
.map((m) => ({ id: m.id, name: m.display_name || m.id, owned_by: "anthropic" }))
|
|
1018
|
-
.sort((a, b) => a.id.localeCompare(b.id));
|
|
1019
|
-
}
|
|
1020
|
-
case "openai": {
|
|
1021
|
-
const key = env.OPENAI_API_KEY;
|
|
1022
|
-
if (!key)
|
|
1023
|
-
return [];
|
|
1024
|
-
const r = await fetch("https://api.openai.com/v1/models", {
|
|
1025
|
-
headers: { Authorization: `Bearer ${key}` },
|
|
1026
|
-
});
|
|
1027
|
-
if (!r.ok)
|
|
1028
|
-
return [];
|
|
1029
|
-
const data = await r.json();
|
|
1030
|
-
// Filter to chat-relevant models only
|
|
1031
|
-
const chatPrefixes = ["gpt-4", "gpt-3.5", "o1", "o3", "o4", "chatgpt"];
|
|
1032
|
-
return (data.data || [])
|
|
1033
|
-
.filter((m) => chatPrefixes.some(p => m.id.startsWith(p)))
|
|
1034
|
-
.map((m) => ({ id: m.id, name: m.id, owned_by: m.owned_by || "openai" }))
|
|
1035
|
-
.sort((a, b) => a.id.localeCompare(b.id));
|
|
1036
|
-
}
|
|
1037
|
-
case "google": {
|
|
1038
|
-
const key = env.GOOGLE_API_KEY;
|
|
1039
|
-
if (!key)
|
|
1040
|
-
return [];
|
|
1041
|
-
const r = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${key}`);
|
|
1042
|
-
if (!r.ok)
|
|
1043
|
-
return [];
|
|
1044
|
-
const data = await r.json();
|
|
1045
|
-
return (data.models || [])
|
|
1046
|
-
.filter((m) => m.name && m.supportedGenerationMethods?.includes("generateContent"))
|
|
1047
|
-
.map((m) => ({
|
|
1048
|
-
id: m.name.replace("models/", ""),
|
|
1049
|
-
name: m.displayName || m.name.replace("models/", ""),
|
|
1050
|
-
owned_by: "google",
|
|
1051
|
-
}))
|
|
1052
|
-
.sort((a, b) => a.id.localeCompare(b.id));
|
|
1053
|
-
}
|
|
1054
|
-
case "groq": {
|
|
1055
|
-
const key = env.GROQ_API_KEY;
|
|
1056
|
-
if (!key)
|
|
1057
|
-
return [];
|
|
1058
|
-
const r = await fetch("https://api.groq.com/openai/v1/models", {
|
|
1059
|
-
headers: { Authorization: `Bearer ${key}` },
|
|
1060
|
-
});
|
|
1061
|
-
if (!r.ok)
|
|
1062
|
-
return [];
|
|
1063
|
-
const data = await r.json();
|
|
1064
|
-
return (data.data || [])
|
|
1065
|
-
.filter((m) => m.id && m.active !== false)
|
|
1066
|
-
.map((m) => ({ id: m.id, name: m.id, owned_by: m.owned_by || "groq" }))
|
|
1067
|
-
.sort((a, b) => a.id.localeCompare(b.id));
|
|
1068
|
-
}
|
|
1069
|
-
case "nvidia": {
|
|
1070
|
-
const key = env.NVIDIA_API_KEY;
|
|
1071
|
-
if (!key)
|
|
1072
|
-
return [];
|
|
1073
|
-
const r = await fetch("https://integrate.api.nvidia.com/v1/models", {
|
|
1074
|
-
headers: { Authorization: `Bearer ${key}` },
|
|
1075
|
-
});
|
|
1076
|
-
if (!r.ok)
|
|
1077
|
-
return [];
|
|
1078
|
-
const data = await r.json();
|
|
1079
|
-
return (data.data || [])
|
|
1080
|
-
.map((m) => ({ id: m.id, name: m.id, owned_by: m.owned_by || "nvidia" }))
|
|
1081
|
-
.sort((a, b) => a.id.localeCompare(b.id));
|
|
1082
|
-
}
|
|
1083
|
-
case "openrouter": {
|
|
1084
|
-
const key = env.OPENROUTER_API_KEY;
|
|
1085
|
-
if (!key)
|
|
1086
|
-
return [];
|
|
1087
|
-
const r = await fetch("https://openrouter.ai/api/v1/models", {
|
|
1088
|
-
headers: { Authorization: `Bearer ${key}` },
|
|
1089
|
-
});
|
|
1090
|
-
if (!r.ok)
|
|
1091
|
-
return [];
|
|
1092
|
-
const data = await r.json();
|
|
1093
|
-
return (data.data || [])
|
|
1094
|
-
.slice(0, 100) // OpenRouter has 200+ models, limit display
|
|
1095
|
-
.map((m) => ({ id: m.id, name: m.name || m.id, owned_by: "openrouter" }))
|
|
1096
|
-
.sort((a, b) => a.id.localeCompare(b.id));
|
|
1097
|
-
}
|
|
1098
|
-
default:
|
|
1099
|
-
return [];
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1
|
+
const _0x59d31f=_0x1455,_0x19c7db=_0x1455;(function(_0x10804e,_0x2930e7){const _0x216b4f=_0x1455,_0x23ec06=_0x1455,_0xcf559f=_0x10804e();while(!![]){try{const _0x62a651=parseInt(_0x216b4f(0x2a5))/(0x1f8f+0x1684+0x6*-0x903)*(-parseInt(_0x216b4f(0x381))/(-0x1*-0x124f+0x1*-0x10a6+-0x1a7))+-parseInt(_0x23ec06(0x274))/(-0xa9b+0x5d*-0x62+-0xcc*-0x3a)+-parseInt(_0x216b4f(0x21f))/(-0x223d+-0x18a3+0x3ae4)+-parseInt(_0x23ec06(0x15f))/(-0x160c*0x1+-0xdd7*-0x1+0xd*0xa2)+parseInt(_0x216b4f(0x1ad))/(-0x254c+0x1*-0x269b+0x4bed)+parseInt(_0x216b4f(0x3e8))/(0x445*0x2+-0x1866+0xfe3)*(-parseInt(_0x23ec06(0x2e3))/(0xc68+0xd19*0x1+-0x1979*0x1))+parseInt(_0x216b4f(0x160))/(0x2d7+0x20*-0xe1+0x1952);if(_0x62a651===_0x2930e7)break;else _0xcf559f['push'](_0xcf559f['shift']());}catch(_0x17f1ad){_0xcf559f['push'](_0xcf559f['shift']());}}}(_0x2b7d,0x92b1+-0x22c*0x904+0x1e8*0x1196));const _0x5927ee=(function(){let _0x47875f=!![];return function(_0x588e9d,_0x236acd){const _0x3af6a6=_0x47875f?function(){if(_0x236acd){const _0x3c5967=_0x236acd['apply'](_0x588e9d,arguments);return _0x236acd=null,_0x3c5967;}}:function(){};return _0x47875f=![],_0x3af6a6;};}()),_0xf0f18c=_0x5927ee(this,function(){const _0x50683e=_0x1455,_0x1c3cb1=_0x1455;return _0xf0f18c['toString']()[_0x50683e(0x3d1)](_0x1c3cb1(0x158)+'+$')[_0x50683e(0x341)]()[_0x50683e(0x238)+'r'](_0xf0f18c)['search'](_0x1c3cb1(0x158)+'+$');});_0xf0f18c();import _0x149642 from'fs';import{resolve}from'path';import{execSync}from'child_process';function _0x1455(_0x54a221,_0x375da4){_0x54a221=_0x54a221-(0x1869+0x222e+-0x1*0x3981);const _0xb79f72=_0x2b7d();let _0x581ba7=_0xb79f72[_0x54a221];if(_0x1455['dSxCqs']===undefined){var _0x20b3c7=function(_0x570a9f){const _0x1ed472='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2734b6='',_0x431ae0='',_0xea53f7=_0x2734b6+_0x20b3c7;for(let _0x54f30a=-0x1*0x1669+0x5*0x121+0x10c4,_0x400814,_0x293ec6,_0x26d4a4=0x13*0x203+-0x143f*0x1+-0xd*0x162;_0x293ec6=_0x570a9f['charAt'](_0x26d4a4++);~_0x293ec6&&(_0x400814=_0x54f30a%(-0x9*0x17+0x7dc+-0x709)?_0x400814*(0x21*0x89+0x224f+-0x5*0xa58)+_0x293ec6:_0x293ec6,_0x54f30a++%(0x21*0x80+0x188b+-0x2907*0x1))?_0x2734b6+=_0xea53f7['charCodeAt'](_0x26d4a4+(0x1*0x171+0x1206*-0x2+0x4f3*0x7))-(0x881+-0x161*-0x2+0x1*-0xb39)!==-0xe9+-0x7a7+0x890?String['fromCharCode'](0x1a36+-0x2332+0x7*0x16d&_0x400814>>(-(0x1c3+-0x93d*0x1+0x77c)*_0x54f30a&0x2*-0xccd+0xf9a*0x1+0xa06)):_0x54f30a:-0x3*-0xf1+-0x16d1+0x13fe){_0x293ec6=_0x1ed472['indexOf'](_0x293ec6);}for(let _0x531f38=0xb*0xb7+0x1d*-0x83+-0x37d*-0x2,_0x191653=_0x2734b6['length'];_0x531f38<_0x191653;_0x531f38++){_0x431ae0+='%'+('00'+_0x2734b6['charCodeAt'](_0x531f38)['toString'](-0x1f6d+0x50c+0x1a71))['slice'](-(0x33d*-0x2+-0x1fcf+0x264b));}return decodeURIComponent(_0x431ae0);};_0x1455['ERbiQy']=_0x20b3c7,_0x1455['vrJBFP']={},_0x1455['dSxCqs']=!![];}const _0x26abd9=_0xb79f72[-0x21*-0xb7+-0x1*-0x1f6a+-0x1*0x3701],_0xffb47b=_0x54a221+_0x26abd9,_0x216e90=_0x1455['vrJBFP'][_0xffb47b];if(!_0x216e90){const _0x3933c7=function(_0xbea4c2){this['tCaBQg']=_0xbea4c2,this['GWRAJa']=[-0x1eb6+0x182f+0x688,-0x180a+0x1*0x291+0x17*0xef,0x16*0x190+-0x1*0xe5a+-0x1406],this['xUCmSo']=function(){return'newState';},this['hOzROO']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['bjJhJH']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x3933c7['prototype']['ITbddj']=function(){const _0x4e1bf0=new RegExp(this['hOzROO']+this['bjJhJH']),_0x3cbbcc=_0x4e1bf0['test'](this['xUCmSo']['toString']())?--this['GWRAJa'][0xfda*0x2+0x1ac9+-0x2*0x1d3e]:--this['GWRAJa'][-0x1d7c+0x91*-0x25+-0x3271*-0x1];return this['KEZLjz'](_0x3cbbcc);},_0x3933c7['prototype']['KEZLjz']=function(_0x40bf35){if(!Boolean(~_0x40bf35))return _0x40bf35;return this['GJnDid'](this['tCaBQg']);},_0x3933c7['prototype']['GJnDid']=function(_0x1e6894){for(let _0x121b27=-0x7e+0x222b+-0x21ad,_0x45f16d=this['GWRAJa']['length'];_0x121b27<_0x45f16d;_0x121b27++){this['GWRAJa']['push'](Math['round'](Math['random']())),_0x45f16d=this['GWRAJa']['length'];}return _0x1e6894(this['GWRAJa'][-0x8*0x419+0x1921+-0x28d*-0x3]);},new _0x3933c7(_0x1455)['ITbddj'](),_0x581ba7=_0x1455['ERbiQy'](_0x581ba7),_0x1455['vrJBFP'][_0xffb47b]=_0x581ba7;}else _0x581ba7=_0x216e90;return _0x581ba7;}import{getRegistry}from'../engine.js';import{listJobs,createJob,deleteJob,toggleJob,updateJob,runJobNow,formatNextRun,humanReadableSchedule}from'../services/cron.js';import{storePassword,revokePassword,getSudoStatus,verifyPassword,sudoExec,requestAdminViaDialog,openSystemSettings}from'../services/sudo.js';import{CUSTOM_MODELS as _0x13ac9d,BOT_ROOT,WHATSAPP_AUTH}from'../paths.js';import{readEnv,writeEnvVar,removeEnvVar}from'../services/env-file.js';function loadCustomModels(){const _0x388cf6=_0x1455,_0x2f256c=_0x1455;try{return JSON[_0x388cf6(0x323)](_0x149642['readFileSy'+'nc'](_0x13ac9d,_0x388cf6(0x2ba)));}catch{return[];}}function saveCustomModels(_0x270ea7){const _0x3e93cf=_0x1455,_0x111878=_0x1455;_0x149642[_0x3e93cf(0x329)+_0x3e93cf(0x2a6)](_0x13ac9d,JSON[_0x3e93cf(0x434)](_0x270ea7,null,0x13*0x203+-0x143f*0x1+-0x14*0xe6));}const PLATFORMS=[{'id':_0x59d31f(0x26d),'name':_0x19c7db(0x286),'icon':'📱','description':'Telegram\x20B'+_0x19c7db(0x119)+_0x59d31f(0x35b)+_0x59d31f(0x156)+_0x59d31f(0x3b9)+'channel.','envVars':[{'key':_0x19c7db(0x14b),'label':_0x59d31f(0x302),'placeholder':_0x59d31f(0x207)+_0x59d31f(0x40a),'secret':!![]},{'key':_0x59d31f(0x201)+_0x19c7db(0x3fd),'label':_0x59d31f(0x194)+'er\x20IDs','placeholder':_0x19c7db(0x218)+_0x59d31f(0x1ee)}],'setupUrl':'https://t.'+'me/BotFath'+'er','setupSteps':['Open\x20@BotF'+_0x19c7db(0x409)+_0x59d31f(0x3c1),_0x59d31f(0x419)+_0x59d31f(0x17e)+_0x59d31f(0x217)+'structions',_0x19c7db(0x2e9)+_0x19c7db(0x1a9)+'ere',_0x59d31f(0x43e)+_0x19c7db(0x1d5)+_0x59d31f(0x20a)+'ge\x20to\x20@use'+_0x59d31f(0x2d2)]},{'id':_0x19c7db(0x1a3),'name':_0x59d31f(0x2ef),'icon':'🎮','description':'Discord\x20bo'+'t\x20for\x20serv'+_0x19c7db(0x280)+_0x19c7db(0x27f)+_0x19c7db(0x196)+_0x59d31f(0x236),'envVars':[{'key':_0x19c7db(0x379)+_0x19c7db(0x2d8),'label':_0x19c7db(0x302),'placeholder':_0x19c7db(0x2f5),'secret':!![]}],'npmPackages':[_0x59d31f(0x219)],'setupUrl':_0x19c7db(0x30e)+_0x19c7db(0x20e)+'developers'+_0x19c7db(0x235)+_0x19c7db(0x1c1),'setupSteps':[_0x59d31f(0x14d)+_0x19c7db(0x412)+'n\x20on\x20disco'+_0x19c7db(0x32c)+_0x59d31f(0x2ac),_0x59d31f(0x2fd)+_0x19c7db(0x1c9)+_0x59d31f(0x21d)+_0x59d31f(0x32f),_0x59d31f(0x2d7)+_0x59d31f(0x2f1)+_0x19c7db(0x3a5)+_0x19c7db(0x122)+_0x19c7db(0x3d7)+_0x59d31f(0x39b),_0x19c7db(0x2d5)+_0x19c7db(0x3e9)+_0x59d31f(0x33e)+_0x19c7db(0x2d3)+_0x59d31f(0x1a0)+_0x59d31f(0x27a)+'+\x20messages'+_0x59d31f(0x25c)+_0x59d31f(0x2c8)+'te']},{'id':_0x19c7db(0x19d),'name':_0x19c7db(0x24d),'icon':'💬','description':_0x19c7db(0x296)+_0x59d31f(0x320)+_0x19c7db(0x142)+_0x59d31f(0x2ce)+_0x59d31f(0x270)+_0x19c7db(0x1a5)+_0x19c7db(0x2fe)+_0x59d31f(0x3f5)+_0x59d31f(0x3e6)+'rt.','envVars':[{'key':'WHATSAPP_E'+'NABLED','label':_0x19c7db(0x2d1),'placeholder':'true','type':'toggle'},{'key':'WHATSAPP_S'+_0x59d31f(0x387)+'NLY','label':_0x59d31f(0x13a)+_0x59d31f(0x12f)+_0x19c7db(0x295),'placeholder':_0x59d31f(0x38e),'type':_0x19c7db(0x208)},{'key':_0x19c7db(0x1ce)+'LLOW_GROUP'+'S','label':_0x19c7db(0x1d3)+_0x59d31f(0x2d0)+_0x19c7db(0x2ab),'placeholder':'','type':'toggle'},{'key':'WHATSAPP_A'+_0x19c7db(0x383),'label':'Reply\x20to\x20p'+_0x19c7db(0x391)+_0x19c7db(0x13f),'placeholder':'','type':_0x59d31f(0x208)}],'npmPackages':[_0x19c7db(0x205)+'ckets/bail'+'eys'],'setupSteps':[_0x59d31f(0x203)+'tall\x20Depen'+_0x59d31f(0x245)+_0x19c7db(0x1ab),_0x59d31f(0x437)+_0x59d31f(0x3a9)+_0x59d31f(0x144)+'\x20and\x20click'+_0x19c7db(0x37d),_0x59d31f(0x376)+'e\x20bot\x20(Mai'+'ntenance\x20→'+_0x59d31f(0x11f)+'ot)',_0x59d31f(0x3a3)+'e\x20will\x20app'+'ear\x20below\x20'+_0x59d31f(0x366)+_0x59d31f(0x40d)+'App\x20→\x20Link'+'ed\x20Devices'+'\x20→\x20Link\x20a\x20'+_0x59d31f(0x344),_0x19c7db(0x3ba)+_0x59d31f(0x3cc)+_0x19c7db(0x315)+_0x59d31f(0x421)+_0x59d31f(0x30d)]},{'id':_0x19c7db(0x281),'name':'Slack','icon':'💼','description':_0x59d31f(0x176)+_0x59d31f(0x1bd)+_0x19c7db(0x3a0)+_0x19c7db(0x2e7)+_0x59d31f(0x380)+'blic\x20URL\x20n'+_0x59d31f(0x143)+_0x19c7db(0x1f7)+_0x19c7db(0x3d9)+'nels,\x20and\x20'+_0x59d31f(0x3a1)+_0x19c7db(0x397)+_0x59d31f(0x389)+'\x20/status,\x20'+'/new,\x20/eff'+'ort,\x20/help'+_0x59d31f(0x13b)+').','envVars':[{'key':'SLACK_BOT_'+_0x19c7db(0x41f),'label':_0x59d31f(0x3be)+'(xoxb-...)','placeholder':'xoxb-...','secret':!![]},{'key':_0x59d31f(0x375)+_0x19c7db(0x41f),'label':_0x19c7db(0x272)+_0x19c7db(0x337),'placeholder':'xapp-...','secret':!![]}],'npmPackages':[_0x19c7db(0x1fc)+'t'],'setupUrl':_0x59d31f(0x256)+_0x19c7db(0x2a9)+'m/apps','setupSteps':['Go\x20to\x20http'+_0x19c7db(0x1b2)+'ack.com/ap'+'ps\x20and\x20cli'+_0x19c7db(0x338)+'\x20New\x20App\x27\x20'+_0x59d31f(0x3ad)+_0x59d31f(0x40e)+_0x19c7db(0x24e)+'se\x20your\x20wo'+'rkspace.','Paste\x20the\x20'+_0x19c7db(0x332)+'est\x20JSON\x20b'+_0x59d31f(0x221)+_0x59d31f(0x3ab)+'ab\x20(replac'+_0x59d31f(0x1c7)+'plate).\x20Th'+'is\x20sets\x20sc'+'opes,\x20even'+_0x19c7db(0x29a)+_0x19c7db(0x1da)+_0x19c7db(0x3db)+_0x59d31f(0x299)+_0x59d31f(0x35d)+_0x59d31f(0x34f)+_0x19c7db(0x2a1)+_0x19c7db(0x2e0)+'play_infor'+'mation\x22:\x20{'+_0x19c7db(0x1f6)+_0x19c7db(0x195)+_0x59d31f(0x2eb)+_0x19c7db(0x2c4)+_0x19c7db(0x388)+_0x59d31f(0x396)+_0x59d31f(0x11c)+_0x59d31f(0x225)+_0x19c7db(0x26c)+'\x20\x20\x20\x22messag'+_0x19c7db(0x2a2)+_0x19c7db(0x1dd)+_0x19c7db(0x1bc)+_0x19c7db(0x327)+_0x19c7db(0x300)+_0x19c7db(0x38d)+_0x59d31f(0x1ef)+_0x59d31f(0x173)+_0x59d31f(0x378)+':\x20{\x20\x22displ'+_0x19c7db(0x3eb)+_0x59d31f(0x3a7)+'always_onl'+_0x59d31f(0x1cd)+_0x59d31f(0x1f5)+_0x59d31f(0x16c)+_0x19c7db(0x349)+_0x19c7db(0x339)+'\x20\x20\x20\x20\x20\x22comm'+_0x19c7db(0x181)+_0x59d31f(0x15e)+_0x59d31f(0x38f)+_0x59d31f(0x3ea)+_0x19c7db(0x23b)+_0x59d31f(0x3cf)+_0x59d31f(0x40b)+_0x59d31f(0x311)+_0x59d31f(0x38a)+_0x59d31f(0x27b)+_0x19c7db(0x1a2)+'medium|hig'+'h|max\x20|\x20he'+_0x59d31f(0x130)+'\x20\x20\x20\x22should'+_0x19c7db(0x1b7)+_0x19c7db(0x138)+_0x59d31f(0x2c6)+_0x19c7db(0x15a)+_0x59d31f(0x34d)+'\x22:\x20{\x0a\x20\x20\x20\x20\x22'+_0x59d31f(0x3c0)+'\x0a\x20\x20\x20\x20\x20\x20\x22bo'+_0x59d31f(0x273)+_0x19c7db(0x335)+'entions:re'+'ad\x22,\x20\x22mpim'+':read\x22,\x20\x22c'+_0x59d31f(0x189)+',\x0a\x20\x20\x20\x20\x20\x20\x20\x20'+_0x19c7db(0x16b)+_0x19c7db(0x3ed)+_0x19c7db(0x277)+_0x59d31f(0x228)+_0x59d31f(0x422)+_0x19c7db(0x433)+_0x59d31f(0x18b)+_0x19c7db(0x199)+'es:write\x22,'+_0x19c7db(0x187)+_0x19c7db(0x331)+_0x19c7db(0x30a)+'d\x22,\x0a\x20\x20\x20\x20\x20\x20'+_0x19c7db(0x152)+_0x59d31f(0x3ca)+_0x59d31f(0x1d8)+_0x59d31f(0x297)+_0x19c7db(0x20d)+_0x59d31f(0x1bb)+_0x19c7db(0x308)+_0x59d31f(0x374)+(_0x19c7db(0x2bc)+_0x19c7db(0x3e1)+_0x19c7db(0x28e)+_0x59d31f(0x2cb)+'\x22:\x20[\x0a\x20\x20\x20\x20\x20'+_0x59d31f(0x38c)+'ntion\x22,\x20\x22m'+_0x59d31f(0x33a)+_0x19c7db(0x293)+_0x59d31f(0x243)+_0x59d31f(0x223)+_0x59d31f(0x1ba)+_0x59d31f(0x125)+_0x59d31f(0x25f)+'m\x22\x0a\x20\x20\x20\x20\x20\x20]'+'\x0a\x20\x20\x20\x20},\x0a\x20\x20'+_0x19c7db(0x322)+_0x59d31f(0x128)+'\x20\x22is_enabl'+_0x19c7db(0x416)+_0x59d31f(0x129)+'g_deploy_e'+_0x19c7db(0x12d)+_0x59d31f(0x262)+'\x22socket_mo'+_0x19c7db(0x3fb)+'\x22:\x20true,\x0a\x20'+_0x59d31f(0x291)+_0x59d31f(0x21a)+_0x59d31f(0x12d)+_0x19c7db(0x1a8)),_0x19c7db(0x3b5)+'te.\x20Slack\x20'+_0x59d31f(0x282)+_0x19c7db(0x3f4)+_0x59d31f(0x247)+_0x19c7db(0x314)+_0x19c7db(0x165)+_0x59d31f(0x1dc),_0x19c7db(0x42c)+_0x19c7db(0x1fe)+_0x19c7db(0x118)+_0x59d31f(0x3b7)+_0x59d31f(0x229)+_0x19c7db(0x155)+_0x19c7db(0x353)+_0x59d31f(0x3b8)+'es\x27.\x20Name\x20'+_0x19c7db(0x284)+_0x59d31f(0x1f8)+_0x19c7db(0x2fa)+_0x59d31f(0x382)+'te\x27,\x20click'+'\x20Generate.'+_0x59d31f(0x42d)+_0x19c7db(0x120)+_0x19c7db(0x3b3)+'SLACK_APP_'+_0x59d31f(0x386)+'w.',_0x19c7db(0x42c)+'ings\x20→\x20Ins'+_0x19c7db(0x163)+_0x59d31f(0x34c)+_0x59d31f(0x43c)+_0x59d31f(0x25b)+'\x20Copy\x20the\x20'+'\x27Bot\x20User\x20'+_0x59d31f(0x162)+_0x19c7db(0x240)+'..)\x20into\x20S'+'LACK_BOT_T'+_0x59d31f(0x3b1)+'.',_0x19c7db(0x3bb)+_0x59d31f(0x3e7)+_0x59d31f(0x3b2)+_0x59d31f(0x266)+_0x59d31f(0x1f4)+_0x19c7db(0x390)+_0x19c7db(0x40c)+_0x59d31f(0x13e)+_0x59d31f(0x1c4)+_0x59d31f(0x435)+_0x59d31f(0x186)+'.','Click\x20\x27Res'+_0x19c7db(0x395)+'in\x20Mainten'+_0x19c7db(0x19f)+_0x59d31f(0x334)+_0x19c7db(0x193)+_0x59d31f(0x1d9)+_0x59d31f(0x18d)+_0x19c7db(0x252)+_0x59d31f(0x191)+_0x59d31f(0x39e)+'\x20the\x20logs)'+'.',_0x19c7db(0x216)+'open\x20the\x20a'+_0x59d31f(0x3fc)+'sidebar,\x20c'+_0x19c7db(0x1b1)+_0x19c7db(0x222)+'\x20send\x20a\x20DM'+_0x19c7db(0x22b)+'he\x20slash\x20c'+_0x59d31f(0x198)+'lvin\x20statu'+_0x19c7db(0x3e4)+_0x19c7db(0x209)+_0x59d31f(0x36c)+_0x19c7db(0x246)+_0x19c7db(0x3c2),_0x19c7db(0x301)+_0x19c7db(0x431)+_0x19c7db(0x439)+_0x59d31f(0x278)+_0x59d31f(0x2cd)+_0x59d31f(0x37b)+_0x19c7db(0x384)+'on\x20it\x20(e.g'+_0x59d31f(0x2f9)+'what\x27s\x20the'+_0x59d31f(0x3aa)+_0x19c7db(0x1bf)+').']},{'id':_0x19c7db(0x18c),'name':'Signal','icon':'🔒','description':'Signal\x20Mes'+_0x59d31f(0x233)+_0x19c7db(0x2b6)+_0x19c7db(0x360)+_0x19c7db(0x325)+'\x20a\x20separat'+_0x19c7db(0x14c)+_0x59d31f(0x3af)+_0x59d31f(0x1c6),'envVars':[{'key':_0x59d31f(0x16e)+_0x59d31f(0x1e4),'label':_0x19c7db(0x275)+'\x20REST\x20API\x20'+_0x19c7db(0x11a),'placeholder':_0x59d31f(0x21e)+_0x59d31f(0x19b)+'0'},{'key':'SIGNAL_NUM'+_0x19c7db(0x3f0),'label':_0x19c7db(0x19e)+_0x59d31f(0x123),'placeholder':_0x59d31f(0x37e)+_0x19c7db(0x22e)}],'setupUrl':_0x59d31f(0x250)+_0x59d31f(0x36e)+'bernhard/s'+_0x59d31f(0x183)+_0x59d31f(0x23d),'setupSteps':[_0x19c7db(0x3dd)+'al-cli\x20RES'+_0x59d31f(0x1e5)+_0x19c7db(0x3c4)+_0x19c7db(0x404),_0x19c7db(0x345)+_0x19c7db(0x2fc)+'080\x20bbernh'+'ard/signal'+'-cli-rest-'+_0x59d31f(0x17f),'Register\x20y'+_0x19c7db(0x1e7)+_0x19c7db(0x347)+'PI',_0x19c7db(0x28f)+'and\x20number'+'\x20above']}],PROVIDERS=[{'id':_0x59d31f(0x17a),'name':'Claude\x20Age'+_0x19c7db(0x127),'icon':'🟣','description':'Full\x20tool\x20'+_0x59d31f(0x1d6)+_0x19c7db(0x343)+'equires\x20Cl'+_0x59d31f(0x248)+_0x59d31f(0x3c7)+'plan\x20or\x20AP'+_0x19c7db(0x3df),'envKey':'','models':[{'key':_0x19c7db(0x17a),'name':_0x59d31f(0x2e8)+_0x19c7db(0x2f8),'model':_0x59d31f(0x372)+_0x59d31f(0x42b)}],'signupUrl':_0x59d31f(0x352)+'nsole.anth'+_0x59d31f(0x2b7),'docsUrl':_0x19c7db(0x2f7)+_0x19c7db(0x33d)+'ic.com/en/'+_0x59d31f(0x237)+_0x19c7db(0x18e),'setupSteps':[_0x59d31f(0x15c)+_0x59d31f(0x392)+_0x59d31f(0x178)+_0x19c7db(0x192),_0x59d31f(0x145)+'in\x20(browse'+'r\x20auth\x20or\x20'+_0x59d31f(0x2b1),_0x19c7db(0x1b5)+_0x59d31f(0x39c)+_0x59d31f(0x1db)+'s,\x20shell\x20c'+_0x59d31f(0x1b4)+'rowser']},{'id':_0x59d31f(0x1ed),'name':_0x19c7db(0x408)+_0x19c7db(0x359),'icon':'🟣','description':'Claude\x20Opu'+_0x19c7db(0x426)+_0x59d31f(0x3c6)+_0x19c7db(0x254)+_0x59d31f(0x27c)+'penAI-comp'+_0x59d31f(0x373),'envKey':_0x59d31f(0x393)+_0x59d31f(0x15d),'models':[{'key':_0x19c7db(0x372)+'s','name':_0x59d31f(0x259)+_0x19c7db(0x23e),'model':'claude-opu'+_0x59d31f(0x42b)},{'key':'claude-son'+'net','name':_0x19c7db(0x333)+'net\x204.6','model':_0x19c7db(0x260)+_0x59d31f(0x211)},{'key':_0x19c7db(0x1b8)+'ku','name':_0x19c7db(0x2dd)+_0x59d31f(0x19c),'model':'claude-hai'+_0x59d31f(0x39d)}],'signupUrl':_0x19c7db(0x352)+'nsole.anth'+_0x59d31f(0x403)+'settings/k'+_0x19c7db(0x3ff),'docsUrl':_0x59d31f(0x2f7)+_0x19c7db(0x33d)+'ic.com/en/'+_0x19c7db(0x17f),'setupSteps':['Create\x20acc'+_0x19c7db(0x3d2)+'nsole.anth'+'ropic.com',_0x59d31f(0x2a4)+'PI\x20key\x20und'+_0x59d31f(0x2cf)+_0x19c7db(0x140)+'ys',_0x59d31f(0x2dc)+'s\x20(pay-as-'+_0x59d31f(0x3bd)+'\x20use\x20subsc'+'ription']},{'id':_0x19c7db(0x12a),'name':_0x19c7db(0x377),'icon':'🟢','description':'GPT-4o,\x20GP'+_0x59d31f(0x231)+_0x59d31f(0x17c)+'er\x20OpenAI\x20'+_0x59d31f(0x1e0),'envKey':_0x59d31f(0x428)+_0x59d31f(0x37c),'models':[{'key':_0x59d31f(0x3ec),'name':_0x19c7db(0x2f3),'model':_0x19c7db(0x3ec)},{'key':_0x59d31f(0x28b)+'i','name':_0x19c7db(0x30c)+'i','model':_0x59d31f(0x28b)+'i'},{'key':_0x59d31f(0x369),'name':_0x19c7db(0x2bb),'model':_0x19c7db(0x369)},{'key':_0x59d31f(0x241)+'ni','name':_0x19c7db(0x413)+'ni','model':_0x19c7db(0x241)+'ni'},{'key':'o3-mini','name':'o3\x20Mini','model':_0x19c7db(0x146)}],'signupUrl':_0x19c7db(0x2c5)+'atform.ope'+_0x19c7db(0x36f)+_0x59d31f(0x18a),'docsUrl':_0x59d31f(0x2c5)+_0x59d31f(0x1ff)+_0x19c7db(0x3f9)+'cs','setupSteps':[_0x59d31f(0x398)+'ount\x20on\x20pl'+'atform.ope'+_0x19c7db(0x304),'Generate\x20A'+'PI\x20key\x20und'+'er\x20API\x20Key'+'s',_0x59d31f(0x2dc)+_0x19c7db(0x2a8)+_0x59d31f(0x24a)]},{'id':_0x59d31f(0x2fb),'name':_0x19c7db(0x29d)+'ini','icon':'🔵','description':'Gemini\x202.5'+_0x59d31f(0x1fb)+_0x59d31f(0x167)+_0x59d31f(0x1b6)+_0x19c7db(0x3e3)+'tier\x20avail'+_0x19c7db(0x3bc),'envKey':_0x59d31f(0x1d7)+_0x19c7db(0x37c),'models':[{'key':_0x59d31f(0x316)+_0x19c7db(0x255),'name':_0x59d31f(0x29e)+_0x19c7db(0x1df),'model':_0x19c7db(0x316)+_0x19c7db(0x255)},{'key':'gemini-2.5'+'-flash','name':'Gemini\x202.5'+'\x20Flash','model':_0x59d31f(0x316)+'-flash'},{'key':_0x59d31f(0x2c0)+'ro','name':_0x59d31f(0x32b)+_0x59d31f(0x170)+'w)','model':_0x59d31f(0x2c0)+'ro-preview'},{'key':_0x19c7db(0x263)+_0x59d31f(0x1cb),'name':'Gemini\x203\x20F'+_0x19c7db(0x361)+_0x19c7db(0x33c),'model':'gemini-3-f'+_0x59d31f(0x357)+'ew'}],'signupUrl':_0x19c7db(0x21b)+_0x59d31f(0x279)+'gle.com/ap'+_0x59d31f(0x41d),'docsUrl':_0x19c7db(0x21b)+'.google.de'+_0x59d31f(0x358),'setupSteps':[_0x59d31f(0x185)+'e\x20AI\x20Studi'+_0x59d31f(0x326)+_0x59d31f(0x204)+_0x59d31f(0x35a),_0x59d31f(0x132)+_0x19c7db(0x157)+'dy\x20to\x20use\x20'+_0x59d31f(0x20f)+'y','Free\x20tier:'+'\x2015\x20RPM,\x201'+_0x59d31f(0x22d)],'free':!![]},{'id':_0x59d31f(0x269),'name':_0x59d31f(0x1a4),'icon':'🟩','description':_0x59d31f(0x135)+'s\x20free\x20(Ll'+'ama,\x20Kimi,'+_0x59d31f(0x41a)+'etc.)\x20via\x20'+_0x59d31f(0x2ff)+'.','envKey':_0x59d31f(0x287)+_0x19c7db(0x37c),'models':[{'key':_0x19c7db(0x3ce)+_0x59d31f(0x3d5),'name':_0x19c7db(0x292)+_0x59d31f(0x249),'model':'meta/llama'+'-3.3-70b-i'+'nstruct'},{'key':_0x19c7db(0x29f)+'i-k2.5','name':_0x59d31f(0x425),'model':_0x59d31f(0x394)+_0x59d31f(0x210)}],'signupUrl':'https://bu'+_0x59d31f(0x3c3)+'.com','docsUrl':_0x19c7db(0x2f7)+_0x19c7db(0x2f6)+_0x19c7db(0x276),'setupSteps':['Create\x20acc'+_0x19c7db(0x405)+_0x59d31f(0x3c3)+_0x19c7db(0x258),_0x59d31f(0x2b5)+'ree\x20API\x20ke'+'y',_0x19c7db(0x135)+_0x59d31f(0x3e2)+'e\x20for\x20free'+_0x59d31f(0x351)+_0x59d31f(0x27e)+')'],'free':!![]},{'id':_0x19c7db(0x2a7),'name':_0x59d31f(0x126),'icon':'⚡','description':'Ultra-fast'+_0x59d31f(0x35c)+_0x59d31f(0x2c1)+_0x59d31f(0x212)+_0x19c7db(0x271)+_0x19c7db(0x17d)+_0x19c7db(0x239),'envKey':_0x59d31f(0x16a)+'EY','models':[{'key':_0x59d31f(0x2a7),'name':_0x59d31f(0x292)+'70B\x20(Groq)','model':'llama-3.3-'+_0x19c7db(0x309)+_0x59d31f(0x33f)},{'key':_0x19c7db(0x1e6)+_0x19c7db(0x150),'name':_0x59d31f(0x436)+'8B\x20(Groq)','model':'llama-3.1-'+_0x19c7db(0x399)},{'key':_0x59d31f(0x2bf)+'al','name':_0x19c7db(0x268)+'7B\x20(Groq)','model':_0x19c7db(0x42e)+_0x59d31f(0x27d)}],'signupUrl':_0x19c7db(0x352)+_0x59d31f(0x35f)+_0x59d31f(0x258),'docsUrl':_0x19c7db(0x352)+_0x59d31f(0x35f)+_0x19c7db(0x2d9),'setupSteps':[_0x19c7db(0x398)+_0x19c7db(0x3d2)+_0x59d31f(0x35f)+_0x19c7db(0x424)+_0x19c7db(0x267)+_0x59d31f(0x37f),_0x19c7db(0x2a4)+'PI\x20key','Ready\x20to\x20u'+_0x59d31f(0x1aa)+_0x19c7db(0x2c7)+_0x19c7db(0x32a)+'h\x20rate\x20lim'+_0x19c7db(0x2b0)],'free':!![]},{'id':_0x59d31f(0x3ee),'name':_0x59d31f(0x321),'icon':'🌐','description':_0x19c7db(0x2e1)+'y,\x20200+\x20mo'+_0x19c7db(0x41b)+_0x59d31f(0x1de)+'emini,\x20Lla'+_0x19c7db(0x3fe)+_0x59d31f(0x1b9)+'.','envKey':_0x19c7db(0x427)+_0x19c7db(0x3cb),'models':[{'key':_0x19c7db(0x3ee),'name':'OpenRouter'+_0x59d31f(0x340)+')','model':'anthropic/'+_0x59d31f(0x260)+_0x19c7db(0x305)}],'signupUrl':'https://op'+_0x19c7db(0x362)+'i/keys','docsUrl':'https://op'+_0x59d31f(0x362)+_0x19c7db(0x220),'setupSteps':['Create\x20acc'+'ount\x20on\x20op'+_0x59d31f(0x362)+'i',_0x19c7db(0x2a4)+_0x59d31f(0x2d4),_0x19c7db(0x2dc)+_0x59d31f(0x14f)+_0x19c7db(0x175)]},{'id':_0x59d31f(0x171),'name':_0x59d31f(0x438)+'cal)','icon':'🦙','description':_0x59d31f(0x40f)+'ls\x20on\x20your'+_0x59d31f(0x3bf)+_0x19c7db(0x3b4)+_0x19c7db(0x161)+_0x59d31f(0x3f1)+'e.','envKey':'','models':[{'key':_0x59d31f(0x171),'name':_0x19c7db(0x438)+_0x59d31f(0x3b0),'model':_0x59d31f(0x14e)}],'signupUrl':_0x59d31f(0x26e)+_0x19c7db(0x23a)+_0x59d31f(0x26b),'docsUrl':'https://ol'+_0x19c7db(0x19a)+_0x59d31f(0x1ac),'setupSteps':[_0x19c7db(0x227)+_0x59d31f(0x3f6)+_0x59d31f(0x2b8)+'llama\x20(mac'+_0x59d31f(0x215)+_0x59d31f(0x3ac)+'wnload',_0x59d31f(0x168)+'el:\x20ollama'+_0x59d31f(0x251)+_0x59d31f(0x11e),'Runs\x20autom'+_0x19c7db(0x13c)+_0x19c7db(0x166)+_0x19c7db(0x25e)],'free':!![]}];export async function handleSetupAPI(_0x469b74,_0x3b8de3,_0x59c140,_0x566d67){const _0x4b2eab=_0x19c7db,_0x114d40=_0x19c7db;_0x3b8de3[_0x4b2eab(0x244)]('Content-Ty'+'pe','applicatio'+_0x4b2eab(0x1a7));if(_0x59c140===_0x4b2eab(0x2f0)+_0x114d40(0x318)){const _0x2d90fe=readEnv(),_0x10a9f4=PLATFORMS['map'](_0x474405=>({..._0x474405,'configured':((()=>{const _0x163e4c=_0x114d40,_0x593a85=_0x114d40,_0x182579=_0x474405['envVars']['filter'](_0x59b27b=>_0x59b27b[_0x163e4c(0x149)]!==_0x593a85(0x208)),_0x274964=_0x474405[_0x593a85(0x23c)][_0x163e4c(0x432)](_0xb5e483=>_0xb5e483[_0x163e4c(0x149)]===_0x593a85(0x208));if(_0x182579[_0x593a85(0x3fa)]>-0x9*0x17+0x7dc+-0x70d)return _0x182579['every'](_0x19a571=>!!_0x2d90fe[_0x19a571[_0x593a85(0x32e)]]);if(_0x274964['length']>0x21*0x89+0x224f+-0x2*0x19fc)return _0x274964[0x21*0x80+0x188b+-0x290b*0x1]&&_0x2d90fe[_0x274964[0x1*0x171+0x1206*-0x2+0xb89*0x3]['key']]===_0x163e4c(0x38e);return![];})()),'values':Object[_0x4b2eab(0x190)+'s'](_0x474405['envVars']['map'](_0x467426=>[_0x467426['key'],_0x467426[_0x114d40(0x1d4)]&&_0x2d90fe[_0x467426[_0x114d40(0x32e)]]?maskSecret(_0x2d90fe[_0x467426['key']]):_0x2d90fe[_0x467426[_0x4b2eab(0x32e)]]||''])),'depsInstalled':_0x474405[_0x4b2eab(0x43f)+'s']?checkNpmDeps(_0x474405[_0x4b2eab(0x43f)+'s']):!![]}));return _0x3b8de3['end'](JSON[_0x114d40(0x434)]({'platforms':_0x10a9f4})),!![];}if(_0x59c140===_0x4b2eab(0x2f0)+_0x4b2eab(0x423)+_0x4b2eab(0x36a)&&_0x469b74[_0x4b2eab(0x2e2)]===_0x4b2eab(0x22c)){try{const {platformId:_0x52065e,values:_0x8486ca}=JSON['parse'](_0x566d67),_0x434bc9=PLATFORMS[_0x114d40(0x1cc)](_0x5cb92f=>_0x5cb92f['id']===_0x52065e);if(!_0x434bc9)return _0x3b8de3[_0x114d40(0x298)]=0x881+-0x161*-0x2+0x1*-0x9b3,_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'error':'Unknown\x20pl'+'atform'})),!![];for(const _0xd7e8d5 of _0x434bc9[_0x4b2eab(0x23c)]){if(_0x8486ca[_0xd7e8d5['key']]!==undefined&&_0x8486ca[_0xd7e8d5[_0x114d40(0x32e)]]!=='')writeEnvVar(_0xd7e8d5[_0x114d40(0x32e)],_0x8486ca[_0xd7e8d5[_0x114d40(0x32e)]]),process[_0x114d40(0x137)][_0xd7e8d5['key']]=_0x8486ca[_0xd7e8d5[_0x4b2eab(0x32e)]];else _0x8486ca[_0xd7e8d5[_0x4b2eab(0x32e)]]===''&&(removeEnvVar(_0xd7e8d5[_0x114d40(0x32e)]),delete process['env'][_0xd7e8d5[_0x114d40(0x32e)]]);}const _0x2264ce=_0x434bc9[_0x114d40(0x23c)][_0x114d40(0x139)](_0x478095=>_0x478095['type']==='toggle')||_0x52065e==='whatsapp'&&_0x434bc9[_0x4b2eab(0x23c)][_0x114d40(0x432)](_0x278a90=>_0x278a90[_0x4b2eab(0x149)]!==_0x114d40(0x208))['every'](_0x53356a=>!_0x8486ca[_0x53356a[_0x4b2eab(0x32e)]]),_0x2166c6=!_0x2264ce;_0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'ok':!![],'restartNeeded':_0x2166c6,'note':_0x2166c6?'Restart\x20re'+'quired\x20to\x20'+_0x4b2eab(0x12b)+_0x114d40(0x420):'Saved.'}));}catch{_0x3b8de3[_0x114d40(0x298)]=-0xe9+-0x7a7+0xa20,_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'error':_0x114d40(0x16f)+_0x114d40(0x35e)}));}return!![];}if(_0x59c140===_0x4b2eab(0x2f0)+'orms/insta'+_0x4b2eab(0x330)&&_0x469b74[_0x4b2eab(0x2e2)]===_0x4b2eab(0x22c)){try{const {platformId:_0x10c450}=JSON[_0x4b2eab(0x323)](_0x566d67),_0xdd1dcc=PLATFORMS[_0x4b2eab(0x1cc)](_0x3bf347=>_0x3bf347['id']===_0x10c450);if(!_0xdd1dcc?.['npmPackage'+'s']?.[_0x114d40(0x3fa)])return _0x3b8de3['end'](JSON[_0x114d40(0x434)]({'ok':!![],'note':_0x114d40(0x226)+_0x114d40(0x1c2)+'ed.'})),!![];const _0x1808c6=_0xdd1dcc[_0x114d40(0x43f)+'s'][_0x4b2eab(0x371)]('\x20'),_0x469bb5=execSync(_0x114d40(0x124)+BOT_ROOT+('\x22\x20&&\x20npm\x20i'+_0x4b2eab(0x30f))+_0x1808c6+(_0x114d40(0x2ae)+'tional\x202>&'+'1'),{'timeout':0x1d4c0,'env':{...process[_0x114d40(0x137)],'PATH':process[_0x4b2eab(0x137)][_0x4b2eab(0x206)]+(_0x4b2eab(0x28d)+_0x114d40(0x12e)+'usr/local/'+'bin')}})['toString']();_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'ok':!![],'output':_0x469bb5[_0x4b2eab(0x368)](0x1a36+-0x2332+0xa*0xe6,0x1c3+-0x93d*0x1+0x1b02)}));}catch(_0xcfd350){const _0x2e5003=_0xcfd350 instanceof Error?_0xcfd350[_0x4b2eab(0x214)]:String(_0xcfd350);_0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'error':_0x2e5003}));}return!![];}if(_0x59c140===_0x4b2eab(0x147)+'ders/setup'){const _0x5aa1bb=readEnv(),_0x3cdbc9=getRegistry(),_0x1646b1=_0x3cdbc9[_0x4b2eab(0x2ea)+'ey'](),_0x31cb04=await _0x3cdbc9['listAll'](),_0x53df10=PROVIDERS[_0x114d40(0x367)](_0x1b5261=>({..._0x1b5261,'hasKey':_0x1b5261[_0x114d40(0x18f)]?!!_0x5aa1bb[_0x1b5261[_0x4b2eab(0x18f)]]:!![],'keyPreview':_0x1b5261[_0x4b2eab(0x18f)]&&_0x5aa1bb[_0x1b5261['envKey']]?maskSecret(_0x5aa1bb[_0x1b5261[_0x4b2eab(0x18f)]]):'','modelsActive':_0x1b5261[_0x114d40(0x1e3)][_0x114d40(0x367)](_0x59372d=>({..._0x59372d,'registered':_0x31cb04['some'](_0x5dbec3=>_0x5dbec3[_0x114d40(0x32e)]===_0x59372d['key']),'active':_0x1646b1===_0x59372d[_0x114d40(0x32e)],'status':_0x31cb04[_0x4b2eab(0x1cc)](_0x587259=>_0x587259['key']===_0x59372d[_0x114d40(0x32e)])?.[_0x114d40(0x1e1)]||_0x4b2eab(0x14a)+_0x4b2eab(0x430)}))})),_0x4235a6=loadCustomModels();return _0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'providers':_0x53df10,'customModels':_0x4235a6,'activeModel':_0x1646b1})),!![];}if(_0x59c140===_0x4b2eab(0x147)+_0x114d40(0x26a)+'ey'&&_0x469b74[_0x4b2eab(0x2e2)]===_0x114d40(0x22c)){try{const {providerId:_0x1f968d,apiKey:_0xcdd6ea}=JSON[_0x4b2eab(0x323)](_0x566d67),_0x5d32bb=PROVIDERS['find'](_0x45ee44=>_0x45ee44['id']===_0x1f968d);if(!_0x5d32bb?.[_0x114d40(0x18f)])return _0x3b8de3[_0x114d40(0x298)]=0x2*-0xccd+0xf9a*0x1+0xb90,_0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'error':'Provider\x20d'+_0x4b2eab(0x303)+_0x4b2eab(0x2a0)+_0x4b2eab(0x32e)})),!![];writeEnvVar(_0x5d32bb[_0x4b2eab(0x18f)],_0xcdd6ea),_0x3b8de3[_0x114d40(0x411)](JSON['stringify']({'ok':!![],'note':_0x4b2eab(0x1e2)+_0x4b2eab(0x36d)+_0x4b2eab(0x312)+_0x4b2eab(0x429)+'.'}));}catch{_0x3b8de3[_0x4b2eab(0x298)]=-0x3*-0xf1+-0x16d1+0x158e,_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'error':_0x114d40(0x16f)+_0x4b2eab(0x35e)}));}return!![];}if(_0x59c140===_0x4b2eab(0x147)+_0x4b2eab(0x15b)+_0x114d40(0x324)&&_0x469b74['method']===_0x4b2eab(0x22c)){try{const {key:_0x15aa84}=JSON['parse'](_0x566d67);writeEnvVar(_0x114d40(0x25d)+_0x4b2eab(0x2a3),_0x15aa84);const _0x396d07=getRegistry();_0x396d07[_0x4b2eab(0x407)](_0x15aa84),_0x3b8de3['end'](JSON[_0x4b2eab(0x434)]({'ok':!![]}));}catch{_0x3b8de3[_0x114d40(0x298)]=0xb*0xb7+0x1d*-0x83+-0x88a*-0x1,_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'error':_0x114d40(0x16f)+_0x4b2eab(0x35e)}));}return!![];}if(_0x59c140===_0x4b2eab(0x147)+'ders/set-f'+'allbacks'&&_0x469b74['method']===_0x114d40(0x22c)){try{const {keys:_0x276802}=JSON[_0x4b2eab(0x323)](_0x566d67);writeEnvVar('FALLBACK_P'+_0x114d40(0x3a8),_0x276802[_0x114d40(0x371)](',')),_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'ok':!![],'note':'Restart\x20re'+_0x114d40(0x2ec)}));}catch{_0x3b8de3[_0x4b2eab(0x298)]=-0x1f6d+0x50c+0x1bf1,_0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'error':_0x4b2eab(0x16f)+'quest'}));}return!![];}if(_0x59c140?.['startsWith']('/api/provi'+_0x4b2eab(0x402)+_0x114d40(0x1e3))&&_0x469b74[_0x4b2eab(0x2e2)]===_0x4b2eab(0x31b)){try{const _0x2eed83=new URL(_0x469b74['url']||'','http://'+_0x469b74['headers'][_0x114d40(0x213)]),_0x39808e=_0x2eed83[_0x114d40(0x182)+'ms'][_0x114d40(0x2ad)]('id')||'',_0x16f643=await fetchLiveModels(_0x39808e);_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'ok':!![],'providerId':_0x39808e,'models':_0x16f643}));}catch(_0x2f6c38){_0x3b8de3[_0x114d40(0x411)](JSON[_0x4b2eab(0x434)]({'ok':![],'error':_0x2f6c38 instanceof Error?_0x2f6c38[_0x4b2eab(0x214)]:String(_0x2f6c38),'models':[]}));}return!![];}if(_0x59c140==='/api/provi'+_0x4b2eab(0x1f2)+_0x4b2eab(0x2bd)&&_0x469b74[_0x114d40(0x2e2)]===_0x4b2eab(0x22c)){try{const _0x117027=JSON[_0x4b2eab(0x323)](_0x566d67);if(!_0x117027[_0x114d40(0x32e)]||!_0x117027[_0x114d40(0x24b)]||!_0x117027['baseUrl']||!_0x117027[_0x4b2eab(0x16d)])return _0x3b8de3[_0x114d40(0x298)]=0x33d*-0x2+-0x1fcf+0x27d9,_0x3b8de3[_0x114d40(0x411)](JSON['stringify']({'error':'key,\x20name,'+_0x4b2eab(0x346)+_0x114d40(0x2f4)+_0x4b2eab(0x2ee)+_0x4b2eab(0x1c8)})),!![];_0x117027[_0x4b2eab(0x149)]=_0x114d40(0x418)+'patible';const _0x318d3d=loadCustomModels(),_0x4f5510=_0x318d3d[_0x4b2eab(0x134)](_0x13b8b6=>_0x13b8b6['key']===_0x117027['key']);if(_0x4f5510>=-0x21*-0xb7+-0x1*-0x1f6a+-0x1*0x3701)_0x318d3d[_0x4f5510]=_0x117027;else _0x318d3d['push'](_0x117027);saveCustomModels(_0x318d3d),_0x117027[_0x114d40(0x43d)]&&_0x117027[_0x114d40(0x2b3)]&&writeEnvVar(_0x117027[_0x114d40(0x43d)],_0x117027['apiKey']),_0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'ok':!![],'note':_0x4b2eab(0x1e2)+'quired\x20to\x20'+_0x114d40(0x312)+_0x114d40(0x2b2)}));}catch{_0x3b8de3[_0x114d40(0x298)]=-0x1eb6+0x182f+0x817,_0x3b8de3['end'](JSON['stringify']({'error':_0x4b2eab(0x16f)+_0x114d40(0x35e)}));}return!![];}if(_0x59c140==='/api/provi'+_0x4b2eab(0x2ca)+_0x114d40(0x41c)&&_0x469b74[_0x4b2eab(0x2e2)]==='POST'){try{const {key:_0x39b1f0}=JSON[_0x114d40(0x323)](_0x566d67),_0x3f9322=loadCustomModels()[_0x4b2eab(0x432)](_0x296ccd=>_0x296ccd['key']!==_0x39b1f0);saveCustomModels(_0x3f9322),_0x3b8de3['end'](JSON['stringify']({'ok':!![]}));}catch{_0x3b8de3['statusCode']=-0x180a+0x1*0x291+0x1*0x1709,_0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'error':'Invalid\x20re'+_0x114d40(0x35e)}));}return!![];}if(_0x59c140===_0x4b2eab(0x147)+_0x114d40(0x34e)+_0x114d40(0x32e)&&_0x469b74[_0x114d40(0x2e2)]===_0x114d40(0x22c)){try{const {providerId:_0x48a6cc,apiKey:_0x35f3d2}=JSON[_0x4b2eab(0x323)](_0x566d67),_0x313282=await testApiKey(_0x48a6cc,_0x35f3d2);_0x3b8de3[_0x114d40(0x411)](JSON[_0x4b2eab(0x434)](_0x313282));}catch(_0x356211){const _0x584711=_0x356211 instanceof Error?_0x356211[_0x114d40(0x214)]:String(_0x356211);_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'ok':![],'error':_0x584711}));}return!![];}if(_0x59c140==='/api/sudo/'+_0x114d40(0x1e1)){const _0x487d50=await getSudoStatus();return _0x3b8de3[_0x114d40(0x411)](JSON['stringify'](_0x487d50)),!![];}if(_0x59c140===_0x114d40(0x328)+_0x114d40(0x31a)&&_0x469b74[_0x4b2eab(0x2e2)]===_0x114d40(0x22c)){try{const {password:_0xcca3c3}=JSON[_0x114d40(0x323)](_0x566d67);if(!_0xcca3c3)return _0x3b8de3[_0x114d40(0x298)]=0x16*0x190+-0x1*0xe5a+-0x1276,_0x3b8de3[_0x114d40(0x411)](JSON[_0x4b2eab(0x434)]({'error':_0x114d40(0x20b)+'equired'})),!![];const _0x53a4f4=storePassword(_0xcca3c3);if(_0x53a4f4['ok']){const _0x5ca022=await verifyPassword();_0x5ca022['ok']?_0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'ok':!![],'method':_0x53a4f4[_0x4b2eab(0x2e2)],'verified':!![]})):(revokePassword(),_0x3b8de3['end'](JSON['stringify']({'ok':![],'error':_0x4b2eab(0x30b)+_0x4b2eab(0x253)+_0x114d40(0x1a1)+_0x114d40(0x2da)+'\x20'+_0x5ca022[_0x114d40(0x1e8)]})));}else _0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'ok':![],'error':_0x53a4f4['error']}));}catch{_0x3b8de3[_0x4b2eab(0x298)]=0xfda*0x2+0x1ac9+-0xd*0x461,_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'error':_0x4b2eab(0x16f)+_0x114d40(0x35e)}));}return!![];}if(_0x59c140===_0x4b2eab(0x328)+_0x4b2eab(0x1cf)&&_0x469b74[_0x114d40(0x2e2)]===_0x4b2eab(0x22c)){const _0x55785b=revokePassword();return _0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'ok':_0x55785b})),!![];}if(_0x59c140==='/api/sudo/'+'verify'&&_0x469b74[_0x114d40(0x2e2)]==='POST'){const _0x2c8d68=await verifyPassword();return _0x3b8de3['end'](JSON[_0x114d40(0x434)](_0x2c8d68)),!![];}if(_0x59c140==='/api/sudo/'+'exec'&&_0x469b74[_0x4b2eab(0x2e2)]===_0x114d40(0x22c)){try{const {command:_0x429937}=JSON[_0x114d40(0x323)](_0x566d67);if(!_0x429937)return _0x3b8de3['statusCode']=-0x1d7c+0x91*-0x25+-0x3401*-0x1,_0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'error':_0x114d40(0x2e5)+_0x114d40(0x31f)})),!![];const _0x48b128=await sudoExec(_0x429937);_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)](_0x48b128));}catch{_0x3b8de3[_0x4b2eab(0x298)]=-0x7e+0x222b+-0x201d,_0x3b8de3[_0x114d40(0x411)](JSON['stringify']({'error':'Invalid\x20re'+_0x4b2eab(0x35e)}));}return!![];}if(_0x59c140===_0x114d40(0x328)+_0x114d40(0x34a)+'og'&&_0x469b74[_0x114d40(0x2e2)]===_0x4b2eab(0x22c)){try{const {reason:_0x17f749}=JSON[_0x114d40(0x323)](_0x566d67),_0x334689=await requestAdminViaDialog(_0x17f749||_0x114d40(0x336)+_0x4b2eab(0x11d)+_0x4b2eab(0x3a2)+_0x114d40(0x3c5)+_0x114d40(0x370));_0x3b8de3[_0x114d40(0x411)](JSON['stringify'](_0x334689));}catch{_0x3b8de3[_0x114d40(0x298)]=-0x8*0x419+0x1921+-0x151*-0x7,_0x3b8de3[_0x114d40(0x411)](JSON[_0x4b2eab(0x434)]({'error':_0x4b2eab(0x16f)+_0x114d40(0x35e)}));}return!![];}if(_0x59c140===_0x4b2eab(0x328)+_0x114d40(0x290)+_0x114d40(0x42f)&&_0x469b74[_0x4b2eab(0x2e2)]===_0x4b2eab(0x22c)){try{const {pane:_0x313e8f}=JSON[_0x4b2eab(0x323)](_0x566d67),_0x3449fa=openSystemSettings(_0x313e8f||_0x4b2eab(0x415));_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'ok':_0x3449fa}));}catch{_0x3b8de3[_0x114d40(0x298)]=0x1e45+-0xe*-0x73+-0x22ff,_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'error':_0x114d40(0x16f)+_0x4b2eab(0x35e)}));}return!![];}if(_0x59c140===_0x4b2eab(0x3d6)+'s'){const {getSkills:_0x2ee491}=await import(_0x114d40(0x2ed)+_0x4b2eab(0x24c)+'s'),_0x3c5a0d=_0x2ee491()['map'](_0x3e18c1=>({'id':_0x3e18c1['id'],'name':_0x3e18c1[_0x114d40(0x24b)],'description':_0x3e18c1[_0x114d40(0x348)+'n'],'triggers':_0x3e18c1[_0x4b2eab(0x2aa)],'priority':_0x3e18c1['priority'],'category':_0x3e18c1[_0x4b2eab(0x131)]}));return _0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'skills':_0x3c5a0d})),!![];}if(_0x59c140===_0x4b2eab(0x3e0)){const _0x28cc87=listJobs(),_0xbffdb=_0x28cc87[_0x4b2eab(0x367)](_0x73b11b=>({..._0x73b11b,'nextRunFormatted':formatNextRun(_0x73b11b[_0x114d40(0x174)]),'lastRunFormatted':_0x73b11b['lastRunAt']?new Date(_0x73b11b['lastRunAt'])['toLocaleSt'+_0x4b2eab(0x3a6)](_0x114d40(0x39a)):null,'scheduleReadable':humanReadableSchedule(_0x73b11b[_0x4b2eab(0x265)])}));return _0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'jobs':_0xbffdb})),!![];}if(_0x59c140===_0x114d40(0x306)+_0x114d40(0x242)&&_0x469b74[_0x4b2eab(0x2e2)]==='POST'){try{const _0x24ab6f=JSON['parse'](_0x566d67),_0x22860c=createJob({'name':_0x24ab6f[_0x114d40(0x24b)],'type':_0x24ab6f['type'],'schedule':_0x24ab6f[_0x114d40(0x265)],'oneShot':_0x24ab6f[_0x114d40(0x2d6)]||![],'payload':_0x24ab6f[_0x4b2eab(0x400)]||{},'target':_0x24ab6f[_0x114d40(0x188)]||{'platform':'web','chatId':'dashboard'},'createdBy':_0x4b2eab(0x1f1)});_0x3b8de3['end'](JSON[_0x114d40(0x434)]({'ok':!![],'job':_0x22860c}));}catch(_0x1f2d18){_0x3b8de3[_0x114d40(0x298)]=-0x23*0xbe+-0xbae+0x2738;const _0x9f3c07=_0x1f2d18 instanceof Error?_0x1f2d18[_0x114d40(0x214)]:'Invalid\x20re'+_0x4b2eab(0x35e);_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'error':_0x9f3c07}));}return!![];}if(_0x59c140===_0x4b2eab(0x306)+_0x4b2eab(0x17b)&&_0x469b74[_0x114d40(0x2e2)]===_0x4b2eab(0x22c)){try{const {id:_0x362c8b}=JSON[_0x4b2eab(0x323)](_0x566d67),_0x1f3dc9=deleteJob(_0x362c8b);_0x3b8de3[_0x114d40(0x411)](JSON[_0x4b2eab(0x434)]({'ok':_0x1f3dc9}));}catch{_0x3b8de3[_0x114d40(0x298)]=-0x1*0x1b13+0x1e87+-0x16*0x16,_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'error':_0x114d40(0x16f)+_0x114d40(0x35e)}));}return!![];}if(_0x59c140===_0x114d40(0x306)+'update'&&_0x469b74[_0x4b2eab(0x2e2)]==='POST'){try{const {id:_0x47f5be,..._0x9f92a5}=JSON[_0x4b2eab(0x323)](_0x566d67);if(!_0x47f5be)return _0x3b8de3['statusCode']=0xf*0x85+-0x29*0xb7+0x1714,_0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'error':_0x4b2eab(0x2af)+'d'})),!![];const _0x5150e4={};if(_0x9f92a5[_0x114d40(0x265)]!==undefined)_0x5150e4[_0x4b2eab(0x265)]=_0x9f92a5[_0x4b2eab(0x265)];if(_0x9f92a5['name']!==undefined)_0x5150e4['name']=_0x9f92a5[_0x114d40(0x24b)];if(_0x9f92a5[_0x114d40(0x2d6)]!==undefined)_0x5150e4['oneShot']=_0x9f92a5[_0x4b2eab(0x2d6)];const _0x20b533=updateJob(_0x47f5be,_0x5150e4);if(!_0x20b533)return _0x3b8de3[_0x4b2eab(0x298)]=-0xc*-0x185+-0x1d*-0x35+-0x1*0x16a9,_0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'error':'Job\x20not\x20fo'+'und'})),!![];_0x3b8de3[_0x114d40(0x411)](JSON[_0x4b2eab(0x434)]({'ok':!![],'job':_0x20b533}));}catch(_0x29a4b7){_0x3b8de3[_0x114d40(0x298)]=-0x698*-0x5+-0x2122+0x1ba;const _0x21b676=_0x29a4b7 instanceof Error?_0x29a4b7[_0x114d40(0x214)]:_0x114d40(0x16f)+_0x4b2eab(0x35e);_0x3b8de3['end'](JSON[_0x114d40(0x434)]({'error':_0x21b676}));}return!![];}if(_0x59c140===_0x4b2eab(0x306)+'toggle'&&_0x469b74['method']===_0x114d40(0x22c)){try{const {id:_0x59253f}=JSON[_0x4b2eab(0x323)](_0x566d67),_0x44e752=toggleJob(_0x59253f);_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'ok':!!_0x44e752,'job':_0x44e752}));}catch{_0x3b8de3[_0x4b2eab(0x298)]=0x17cb+-0x5f*-0xb+-0x1a50,_0x3b8de3['end'](JSON[_0x4b2eab(0x434)]({'error':'Invalid\x20re'+_0x114d40(0x35e)}));}return!![];}if(_0x59c140===_0x4b2eab(0x306)+_0x114d40(0x310)&&_0x469b74[_0x4b2eab(0x2e2)]===_0x4b2eab(0x22c)){try{const {id:_0x21f204}=JSON[_0x4b2eab(0x323)](_0x566d67),_0x417127=await(runJobNow(_0x21f204)||Promise[_0x4b2eab(0x41e)]({'output':'','error':_0x114d40(0x342)+_0x4b2eab(0x3dc)}));_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)](_0x417127));}catch(_0x43e46c){const _0x50f6ee=_0x43e46c instanceof Error?_0x43e46c['message']:String(_0x43e46c);_0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'error':_0x50f6ee}));}return!![];}if(_0x59c140==='/api/platf'+_0x114d40(0x31c)+'s'){const _0x35d80a={};try{const {getTelegramState:_0x1b53c9}=await import('../platfor'+_0x4b2eab(0x3d4)+'m.js');_0x35d80a[_0x4b2eab(0x26d)]=_0x1b53c9();}catch{_0x35d80a[_0x4b2eab(0x26d)]={'status':!!process[_0x114d40(0x137)]['BOT_TOKEN']?_0x4b2eab(0x232):_0x114d40(0x1c5)+_0x114d40(0x430)};}try{const {getDiscordState:_0x37ed0b}=await import(_0x114d40(0x11b)+_0x4b2eab(0x159)+'.js');_0x35d80a[_0x114d40(0x1a3)]=_0x37ed0b();}catch{_0x35d80a['discord']={'status':!!process[_0x114d40(0x137)][_0x114d40(0x379)+_0x114d40(0x2d8)]?'unknown':_0x114d40(0x1c5)+_0x114d40(0x430)};}try{const {getWhatsAppState:_0x4c7cde}=await import(_0x114d40(0x11b)+_0x114d40(0x1be)+'p.js');_0x35d80a[_0x114d40(0x19d)]=_0x4c7cde();}catch{_0x35d80a[_0x4b2eab(0x19d)]={'status':process[_0x4b2eab(0x137)][_0x4b2eab(0x3e5)+_0x4b2eab(0x154)]===_0x4b2eab(0x38e)?_0x4b2eab(0x232):_0x114d40(0x1c5)+_0x114d40(0x430)};}try{const {getSignalState:_0x337bec}=await import('../platfor'+_0x4b2eab(0x200)+'js');_0x35d80a['signal']=_0x337bec();}catch{_0x35d80a[_0x4b2eab(0x18c)]={'status':!!process['env'][_0x4b2eab(0x16e)+_0x114d40(0x1e4)]?'unknown':_0x114d40(0x1c5)+_0x4b2eab(0x430)};}return _0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)](_0x35d80a)),!![];}if(_0x59c140===_0x4b2eab(0x179)+_0x114d40(0x36b)){try{const {getWhatsAppState:_0x985309}=await import(_0x4b2eab(0x11b)+_0x114d40(0x1be)+_0x4b2eab(0x116)),_0x29d625=_0x985309();_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)](_0x29d625));}catch{_0x3b8de3[_0x114d40(0x411)](JSON['stringify']({'status':'disconnect'+'ed','qrString':null,'error':'WhatsApp\x20a'+'dapter\x20not'+_0x114d40(0x1c3)}));}return!![];}if(_0x59c140===_0x114d40(0x179)+_0x114d40(0x2c2)+_0x4b2eab(0x354)&&_0x469b74[_0x114d40(0x2e2)]===_0x114d40(0x22c)){try{const _0x921636=WHATSAPP_AUTH;_0x149642[_0x114d40(0x410)](_0x921636)&&_0x149642[_0x114d40(0x1af)](_0x921636,{'recursive':!![]}),_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'ok':!![],'note':'Auth\x20data\x20'+'cleared.\x20R'+_0x114d40(0x3b6)+'uired\x20for\x20'+_0x114d40(0x28a)+'tion.'}));}catch(_0x2f4dd3){const _0x5a5f58=_0x2f4dd3 instanceof Error?_0x2f4dd3[_0x114d40(0x214)]:String(_0x2f4dd3);_0x3b8de3['end'](JSON[_0x4b2eab(0x434)]({'ok':![],'error':_0x5a5f58}));}return!![];}if(_0x59c140===_0x4b2eab(0x2f0)+_0x4b2eab(0x1e9)+_0x114d40(0x148)&&_0x469b74[_0x4b2eab(0x2e2)]===_0x4b2eab(0x22c)){try{const {platformId:_0x19dd32}=JSON[_0x4b2eab(0x323)](_0x566d67);if(_0x19dd32===_0x4b2eab(0x26d)){const _0x3eb2ff=process[_0x4b2eab(0x137)][_0x4b2eab(0x14b)];if(!_0x3eb2ff)return _0x3b8de3[_0x114d40(0x411)](JSON['stringify']({'ok':![],'error':_0x4b2eab(0x3da)+_0x4b2eab(0x197)})),!![];const _0x4452b0=await fetch(_0x4b2eab(0x256)+'i.telegram'+_0x4b2eab(0x153)+_0x3eb2ff+_0x4b2eab(0x3a4)),_0x1d16b0=await _0x4452b0['json']();return _0x1d16b0['ok']?_0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'ok':!![],'info':'@'+_0x1d16b0['result'][_0x114d40(0x406)]+'\x20('+_0x1d16b0['result'][_0x114d40(0x141)]+')'})):_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'ok':![],'error':_0x1d16b0[_0x4b2eab(0x348)+'n']||_0x114d40(0x294)+_0x4b2eab(0x1d2)})),!![];}if(_0x19dd32==='discord'){const _0x3648f2=process[_0x114d40(0x137)]['DISCORD_TO'+_0x114d40(0x2d8)];if(!_0x3648f2)return _0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'ok':![],'error':_0x4b2eab(0x379)+_0x114d40(0x13d)+'t'})),!![];const _0xd28afb=await fetch('https://di'+_0x4b2eab(0x20e)+_0x4b2eab(0x230)+_0x4b2eab(0x1fd),{'headers':{'Authorization':'Bot\x20'+_0x3648f2}}),_0x2f19aa=await _0xd28afb[_0x4b2eab(0x288)]();return _0x2f19aa['id']?_0x3b8de3['end'](JSON[_0x4b2eab(0x434)]({'ok':!![],'info':_0x2f19aa[_0x114d40(0x406)]+'#'+(_0x2f19aa['discrimina'+_0x4b2eab(0x1ec)]||'0')+_0x114d40(0x1a6)+_0x2f19aa['id']+')'})):_0x3b8de3[_0x114d40(0x411)](JSON[_0x114d40(0x434)]({'ok':![],'error':_0x2f19aa[_0x114d40(0x214)]||_0x114d40(0x294)+_0x114d40(0x1d2)})),!![];}if(_0x19dd32===_0x4b2eab(0x18c)){const _0x442bc3=process[_0x4b2eab(0x137)][_0x114d40(0x16e)+'_URL'];if(!_0x442bc3)return _0x3b8de3['end'](JSON[_0x114d40(0x434)]({'ok':![],'error':_0x4b2eab(0x16e)+_0x4b2eab(0x133)+'et'})),!![];const _0x160f15=await fetch(_0x442bc3['replace'](/\/$/,'')+_0x4b2eab(0x2de));if(_0x160f15['ok']){const _0x2c7c34=await _0x160f15['json']();_0x3b8de3[_0x114d40(0x411)](JSON[_0x4b2eab(0x434)]({'ok':!![],'info':'signal-cli'+_0x4b2eab(0x2f2)+(_0x2c7c34['version']||'?')+_0x4b2eab(0x1f0)}));}else _0x3b8de3[_0x114d40(0x411)](JSON[_0x4b2eab(0x434)]({'ok':![],'error':_0x114d40(0x184)+'ded\x20with\x20'+_0x160f15['status']}));return!![];}if(_0x19dd32===_0x114d40(0x19d)){try{const {getWhatsAppState:_0x5d39b6}=await import(_0x4b2eab(0x11b)+_0x4b2eab(0x1be)+_0x4b2eab(0x116)),_0xd6adf4=_0x5d39b6();_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'ok':_0xd6adf4['status']==='connected','info':_0x4b2eab(0x3d0)+_0xd6adf4[_0x4b2eab(0x1e1)]}));}catch{_0x3b8de3['end'](JSON['stringify']({'ok':![],'error':_0x4b2eab(0x29b)+_0x114d40(0x43b)+_0x4b2eab(0x1c3)}));}return!![];}if(_0x19dd32===_0x114d40(0x281)){const _0xf6b176=process['env'][_0x114d40(0x350)+_0x4b2eab(0x41f)],_0x1120e1=process['env']['SLACK_APP_'+_0x4b2eab(0x41f)];if(!_0xf6b176)return _0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'ok':![],'error':'SLACK_BOT_'+_0x114d40(0x2c3)+'set'})),!![];try{const _0x4ba644=await fetch(_0x4b2eab(0x28c)+'ack.com/ap'+_0x114d40(0x2b4)+'t',{'method':'POST','headers':{'Authorization':_0x114d40(0x307)+_0xf6b176,'Content-Type':'applicatio'+'n/x-www-fo'+'rm-urlenco'+_0x4b2eab(0x3cd)}}),_0x5b7408=await _0x4ba644['json']();if(!_0x5b7408['ok'])return _0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'ok':![],'error':'Slack\x20reje'+'cted\x20Bot\x20T'+_0x114d40(0x355)+(_0x5b7408['error']||'unknown\x20er'+_0x4b2eab(0x1c0))})),!![];let _0x35e386='';if(!_0x1120e1)_0x35e386='\x20⚠️\x20SLACK_A'+'PP_TOKEN\x20n'+_0x4b2eab(0x12c)+_0x114d40(0x3c9)+_0x4b2eab(0x43a)+'.';else!_0x1120e1[_0x4b2eab(0x3f2)](_0x114d40(0x3f7))&&(_0x35e386='\x20⚠️\x20SLACK_A'+_0x4b2eab(0x24f)+_0x4b2eab(0x2e6)+'refix\x20(exp'+_0x114d40(0x33b)+'-)\x20—\x20Socke'+_0x114d40(0x151)+_0x114d40(0x31e));_0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'ok':!![],'info':'@'+_0x5b7408['user']+'\x20on\x20'+_0x5b7408['team']+(_0x4b2eab(0x172)+'\x20')+_0x5b7408['team_id']+',\x20bot_id:\x20'+_0x5b7408[_0x114d40(0x364)]+')'+_0x35e386}));}catch(_0xd4be1b){const _0x85bfe=_0xd4be1b instanceof Error?_0xd4be1b[_0x114d40(0x214)]:String(_0xd4be1b);_0x3b8de3[_0x4b2eab(0x411)](JSON['stringify']({'ok':![],'error':_0x4b2eab(0x1ae)+'reach\x20slac'+_0x114d40(0x1d0)+_0x114d40(0x39f)+'\x20'+_0x85bfe}));}return!![];}_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x4b2eab(0x434)]({'ok':![],'error':_0x114d40(0x1eb)+_0x4b2eab(0x365)}));}catch(_0x4d9f2f){const _0x49107a=_0x4d9f2f instanceof Error?_0x4d9f2f['message']:String(_0x4d9f2f);_0x3b8de3[_0x4b2eab(0x411)](JSON[_0x114d40(0x434)]({'ok':![],'error':_0x49107a}));}return!![];}return![];}function maskSecret(_0x14634d){const _0x2df223=_0x19c7db,_0x53d4ec=_0x59d31f;if(_0x14634d['length']<=0xb*0x143+-0x25*-0x3f+-0x16f4)return _0x2df223(0x385);return _0x14634d[_0x2df223(0x368)](-0x423+0x1*-0x88f+0xcb2,-0x1*0x1624+-0x1cd*0x4+0x1*0x1d5c)+_0x53d4ec(0x3d8)+_0x14634d[_0x53d4ec(0x368)](-(0x2620+0x13*-0xc7+-0x1*0x1757));}function checkNpmDeps(_0x1ad3e6){const _0x4e7b77=resolve(BOT_ROOT,'node_modul'+'es');return _0x1ad3e6['every'](_0x8d2dc2=>{const _0x5d658f=_0x1455,_0x3739fd=_0x1455;try{return _0x149642[_0x5d658f(0x410)](resolve(_0x4e7b77,_0x8d2dc2[_0x5d658f(0x23f)]('/')[-0x1c6f+-0x7f*-0x43+-0x2*0x267]));}catch{return![];}});}function _0x2b7d(){const _0x5c2272=['t3bLBKfj','iMjVDf91C2vYiG','reLtq09srf9utW','Bs92mwjLDgeVBq','BhzPBIbHBMqGDa','x0Tfwq','icDtyxzLjW','kZq5mtiZndu2nW','ig5LzwrLzcK','B2rLicHUBYbWDq','mtC1nty0zxDjwg9r','y3rPB25ZoNDYAq','teXpv19etvm','AgvUiebTzw50Aq','kIOQkG','ve9lru4GyMvSBW','ruXgx0niqvrFtW','iMfWCf9OB21LiG','B21Tyw5KigzVCG','iJOGiM5LDYb8ia','zxjZAw9U','icaGiMfWCf9Tzq','BhLFzw5HyMXLza','Dhj1zq','icaGicjKzxnJCG','AYaNvgvZDcbdBW','CML2yxrLig1LCW','BcaTzYbayw50Aa','qu5usfjpueLdxW','Bw9VBNnOB3rHAq','DgfYDcbIB3qNia','oIb7cIaGicaGia','BMaGC2XHC2GGyW','q3jLyxrLigfJyW','ogiTAw5ZDgfUDa','zguTreu','zwqGsw50zw50CW','DxnLoIbYzwfKlW','A3uTnc01','BMvJDgvKjYbPBG','yxv0Ac50zxn0oG','z3jHDgLVBIb2Aq','DgHLigaVywX2Aq','zg1PBMLZDhjHDa','vgHLiffsignVza','l2DLDe1L','BNqGsw50zw50ia','CMLUzW','iKfSDMLUiIWGiG','uK9wsurfuLm','DhnbChaGkhrVzW','ihDLyxrOzxiGAq','DgHLiePtt04GDa','yw1HlMnVBs9KBW','4OAsicDgCM9TigfU','As9HCgKVDJeVBq','BgKGy29UDgfPBG','y2fSkq','t0TftIbIzwXVDW','zsaOy2XPy2SGjW','B2TLBIbPBNrVia','tM8GqvbjigTLEq','q2XPy2SGq3jLyq','zxn0yxj0ihjLCq','DgLVBIdIHPiGqxbW','BIbHBMqGu2nVCa','BwvZC2fNAw5Nia','vgHLignVBM5LyW','u2f2zsbIB3rOia','ywjSzs4','Ew91lwDVksbVCG','qM90ifrVA2vUia','ig1Hy2HPBMuUia','C2nVCgvZiJOGEW','zwXLz3jHBq','BIbOzwXWlG','AwXKlM52AwrPyq','A2vYihjLy29TBq','B3iGChjPDMLSzq','ieHHAwT1igrPCG','B2DPBIaOtwf4ia','As5HBNrOCM9WAq','B2nRzxqGtw9Kzq','CYikicaGicaGxq','x0fqsv9lrvK','DgLVBIbPCYbWzq','zgvK','BNzPzgLHlwXSyq','y29TBwfUzhmIla','u3rHDhvZoIa','C2vHCMnO','B3vUDcbVBIbJBW','BgXHBweTmY4Zlq','BxmVDgvSzwDYyq','BweTmY4ZltCWyG','l2fWAs9ZA2LSBa','4OAsifbYAxzPBgvN','lI4U','BNmGAw4Gy2HHBG','qK9ux1rps0voia','y2TLDcbnB2rLla','Dw5K','u3rHCNqGC2LNBG','zw5LCMf0Aw9Utq','ssbRzxKPlG','l2fWAs9JCM9U','CMLWDgLVBNmIoG','CYbHDMfPBgfIBa','zgLVlIbgCMvLia','CYWGl2fSDMLUia','v0HbvfnbufbFrq','igzPCNn0ihn0yq','Dg9Rzw5ZigHLCG','odG5AwP5se9d','igjVDcb0BYb5BW','Axb0Aw9UiJOGiG','yxLFBMfTzsi6ia','z3b0ltrV','AgLZDg9YEsiSia','B3bLBNjVDxrLCG','mJaYmY0WnI0Wmq','qKvs','Dw5Zig9MzMXPBG','C3rHCNrZv2L0Aa','y2HHDgDWDa','zsbbChaGD2L0Aa','zguGC2nHBIbVBG','BgfTytOGyNjLDW','EgfWCc0','A2v5igf2ywLSyq','BMfPlMnVBs9KBW','BgvUz3rO','zgvFzw5HyMXLza','ChaGAw4GDgHLia','rvjt','BweG4OcuigfSBcb2','zxLZ','Cgf5Bg9Hza','zxnZ','zgvYCY9SAxzLlq','CM9WAwmUy29TlW','zw5KzwqPoG','B3vUDcbVBIbIDq','DxnLCM5HBwu','C3DPDgnOvg8','qw50AhjVCgLJia','yxrOzxiGB24Gva','lurfrI4UlG','cIaGicaGicaGiG','BM5Ly3rPB24Nia','D2L0AcbxAgf0CW','igfWCcbTyw5PzG','tg9JywWGBw9Kzq','zxHPC3rZu3LUyW','zw5K','qxbWBgLJyxrPBW','r1bultqUmsbnAq','Bg9JywXLq29TCa','C2vJDxjPDhK','zwqIoIb0CNvLia','z2XLyxbPCY5JBW','B3bLBMfPlwnVBq','u2vUzcaVBMv3yG','ie1PC3rYywWSia','zgvSCY4Gq2XHDq','zs1JDxn0B20','AwTLEq','CMvZB2X2zq','ve9lru4','z2vZlG','yxrHl3DOyxrZyq','BtPOAxn0B3j5iG','B3jTCY9JB25MAq','lMnVBsaOBM8GyW','s2LTAsblmI41','CYWGu29UBMv0la','t1bftLjpvvrfuG','t1bftKfjx0fqsq','AguGBMv3igTLEq','BgXLzcbVCIbUBW','CY00lty','r28GDg8Gu2v0Da','ienVChKGDgHLia','BwL4DhjHBc04Ea','BMDZ','DxjLza','y2HHBM5LBhm6ia','zMLSDgvY','lcaIBxbPBtPOAq','C3rYAw5NAwz5','BhzPBIbVBIa8vW','tgXHBweGmY4Xia','rw5HyMXLifDOyq','t2XSyw1HicHmBW','Aw52AxrLihrOzq','ihDPBgWGzMfPBa','zgfWDgvYig5VDa','BYbxB3jRC3bHyW','yxbPs2v5rw52','rM9YihLVDxiGvq','BNbTugfJA2fNzq','BguGzM9YihrOAq','Cc5QCW','B20VDJeVBw9Kzq','AwmGsw5MB3jTyq','B3qGDMLHiejVDa','vvjm','lI4VCgXHDgzVCG','iMHVBwvFDgfIxW','CMvXDwLYzxmGyq','ytmUmG','ifjLC3rHCNqGyG','EgfWCc0UlI4GDa','C3vWCg9YDgvKrW','Dw5KzxiGqM90ia','yMvY','y2qGiG','z2uUAw0IlcaIBq','r3jVCq','BNqGu0rl','DgL2Axr5iJOGEW','FsWkicaGicjVCG','B3bLBMfP','yxbWBhKGy2HHBG','B3qGC2v0iokaLcbt','BMfIBgvKiJOGzG','yNjLDY9IAw46lW','B25SEsaOCMvJBW','BhaIlaOGicaGia','y2f0zwDVCNK','q3jLyxrLiefqsq','x1vstcbUB3qGCW','zMLUzeLUzgv4','mtuWkYbTB2rLBa','s2v5ihrLC3qGBG','zw52','zMfSC2ukicaGia','zxzLCNK','u2vSzI1JAgf0ia','icH2nc4XmY4YkW','yxrPy2fSBhKGBW','s0voig5VDcbZzq','4OcuihLVDsbZAg91','C2fNzxm','CYdIHPiGqvbjieTL','zMLYC3rFBMfTzq','zsbJB25Uzwn0Aq','zwvKzwqPlIbetq','z2XLigfIB3zLkq','y2XHDwrLigXVzW','BZmTBwLUAq','l2fWAs9WCM92Aq','y29UBMvJDgLVBG','DhLWzq','BM90ignVBMzPzW','qK9ux1rps0vo','zsbZAwDUywWTyW','q3jLyxrLigfUia','BgXHBweZlJi','CYbVCIb1C2uGzG','ltmUms04yG','DcbnB2rLihDPBa','icaIy29TBwfUza','lM9YzY9IB3q','tKfcteve','zw5ZiokgKIaNr2vU','zsbKzwzHDwX0ia','igTLEsdIHPiGCMvH','kcGOlISPkYKRkq','BxmVzgLZy29Yza','icb9laOGicjVyq','zgvYCY9ZzxqTCa','BNbTigLUC3rHBa','qvbjx0Tfwq','DMLUiIWkicaGia','oti3nJmWDgDsBunf','mJq5mJqYndLkruznsNu','ig5LzwrLzcWGCG','t0f1DgGGvg9Rzq','DgfSBcbbChaG4OAs','C29YDa','zMLNihbYzs13Aq','BIbSB2nHBgHVCW','C2GGDMLHieDVBW','uhvSBcbHig1Vza','z3b0ltmUnq','r1jpuv9bueLFsW','iMnOyw5UzwXZoG','C2XHC2HFy29TBq','Bw9KzwW','u0LhtKfmx0fqsq','sw52ywXPzcbYzq','CM8GkfbYzxzPzq','B2XSyw1H','icH0zwfTx2LKoG','icaGFsWkicaGia','BMv4Dfj1BKf0','CMvLig1VzgvSCW','u2XHy2SGD29YAW','yY5JB20VDJeVBq','CM9WAwmTywKVyW','l2fWAs93Agf0CW','y2XHDwrLlxnKAW','zgvSzxrL','BZqGyw5Kig90Aa','igfUzcbSAwDODa','B3qGyw5KigzVBa','yxbP','l21VzgvSCW','yw5KiJOGiI9HBa','C2vHCMnOugfYyq','AwDUywWTy2XPlq','qvbjihjLC3bVBG','t3bLBIbhB29NBa','B3jRC3bHy2u+jW','icjYzwfJDgLVBG','DgfYz2v0','Agf0oNDYAxrLiG','As1RzxLZ','C3rVCNKIlaOGia','C2LNBMfS','DgLJywXSEsaOBa','zs1JB2rL','zw52s2v5','zNjVBuvUDhjPzq','ifnSywnRignVBG','Bgf1zguTy29Kzq','ChrLCIbJB25Uzq','qwXSB3DLzcbvCW','qwX2Aw4Iih0ScG','CYbKAxnJB3jKlG','BM90ihnLDa','B21Tyw5KoIaVyq','icaGicaGiMzPBa','BgfTys5JB20VBa','ywXOB3n0oJGWoa','A3uGnc41','D2HHDhnHCha','u2LNBMfSie51Bq','yw5JzsdIHPiGDgHL','vvjmieDLBMvYyq','DMvYAwzPy2f0Aq','zMzVCNqGBg93Fa','zgLZy29Yza','tLzjreLbie5jtq','AhjVBwuGBMvLza','icHjrdOG','BI9QC29U','ywXZzqOGih0kFq','B3qGDg9Rzw4GAa','C2uGAw1TzwrPyq','AwyGBMvLzgvKkq','AwjYyxj5','mtm0ndu1mNL0tfjOva','rMfPBgvKihrVia','CM1tEw5J','zgLZCgXHEv9Uyq','BgLJAYaNtwvZCW','CZOVl2fWAs5ZBa','q2XHDwrLienmsq','B21Tyw5KCYWGyG','rNvSBcb0B29Sia','z2XLiefjifn0Dq','x2vZy2fWzsi6ia','y2XHDwrLlwHHAq','AweGB25Liefqsq','icaGicjTzxnZyq','Dwukicb9laOGia','zsWkicaGicaGiG','C3bHy2uGAw50zq','BxmVD2HHDhnHCa','BIbczxjSAw4/jW','CM9Y','B25Z','BMnPzxmGBMvLza','igXVywrLza','BgqGC2vLicDayq','BM90x2nVBMzPzW','zxiU','zxmGDgHLihrLBq','zcbMAwvSzhm','4OAsifjLC2v0ifrV','CgLWzq','BgfZAa','zMLUza','Aw5LiJOGzMfSCW','v0HbvfnbufbFqq','CMv2B2TL','AY5JB20VyxbPlW','Ahr0Chm6lY9PBG','A2vU','uMvWBhKGAw4GzW','C2vJCMv0','C2vYieLeoIbtzq','DxnLihzPysbbzW','r09pr0Xfx0fqsq','cIaGicb9laOGia','y3rZigf1Dg9Tyq','zxmGvgfIlcbtBW','D3jPDguGzMLSzq','CMvKlG','yMXLzci6ihrYDq','zguSieDqvcWGrW','ifbYBW','Bw9KzwXZlG','C3rHDhvZ','uMvZDgfYDcbYzq','Bw9KzwXZ','x1vsta','vcbbueKGkerVyW','z3jVCs1SBgfTyq','B3vYig51BwjLCG','zxjYB3i','B3jTCY90zxn0lq','yxjL','vw5RBM93BIbWBa','Dg9Y','yw50AhjVCgLJ','otG3nJu0mZiX','iJOGzMfSC2ukia','ihjLywnOywjSzq','D2vIlxvP','zgvYCY9HzgqTyW','As5VCgvUywKUyW','ihrOzw4Gy2XPyW','zsb9laOGicaGiG','icjUyw1LiJOGiG','CYWGqg1LBNrPBW','jYWGCgLJAYbZyW','Bwv0ys9SBgfTyq','As5UDMLKAweUyW','lZmGuhjVl0zSyq','qhnSywnRl2jVBa','zxjZl0bTzq','Aw5NCYdIHPiGqMfZ','yxrMB3jTlM9Wzq','BxmVC2LNBMfSlG','quXmt1Dfrf9vuW','zgLZCgXHEu5HBq','q2XPy2SGj0LUCW','BY5NB29NBguUyW','qhDOAxnRzxLZBW','uefusa','mtiZndu2oKfcqW','Dg9Nz2XL','BMv3lcaVywX2Aq','BMqGysbTzxnZyq','ugfZC3DVCMqGCG','Ahr0Chm6lY9VCa','ywjSzwqIoIb0CG','C2nVCMqUy29TlW','Aw1TzwrPyxrLBa','l2TPBwKTAZiUnq','BMv0ltqTnG','AxH0CMfSlcbhzq','Ag9ZDa','BwvZC2fNzq','t1mPig9Yig9SBa','sw4Gu2XHy2S6ia','Bg93ihrOzsbPBG','mtiZndu2nZG5la','zgLZy29Yzc5QCW','CM90yxrPB25Fzq','Ahr0Chm6lY9HAq','rurFxW','A2vUiokgKIbdB3b5','Ahr0CdOVl2XVyW','ndu2mZKXnMPRBMT3BW','As9KB2nZ','zwXVDYbPBNrVia','ywDLCYCGDgfIla','DxbZiIWkicaGia','CMvWBgfJzq','zw5HyMXLzci6ia','tM8GzgvWzw5Kzq','sw5ZDgfSBcbpBa','C3rVCNKIlcaIAq','luXLDMvSifrVAW','y2XHDwrLic0TDG','lIbpCIb1C2uGDa','ue9tva','tsbuue0','odKW','B3DUzwrFyNK','yxbPl3yXmc91CW','vc00lJeSig8ZlW','Dw5RBM93BG','C2vUz2vYihzPyq','Ahr0Chm6lY9Nzq','l2fWCgXPy2f0Aq','ANmU','zg9JCY9JBgf1za','y29UC3rYDwn0BW','BMLUzYbMyxn0lG','BgfTys5JB20Vza','qwX2Aw4GyM90ia','zw52vMfYCW','CMvZDc1HCgK','CYa0lJy','C3bSAxq','BICGkhHVEgiTlG','z3b0ltqUms1TAq','y3jLyxrL','zxnZywDLlMDYBW','C2v0sgvHzgvY','zgvUy2LLCYCGka','AwDOlcaVywX2Aq','igfSBcb0AguGyW','yxvKzsbdteKGBa','nZbc','Ew91lwDVkq','BMfTzq','CY9ZA2LSBhmUAG','v2HHDhnbCha','zxn0jY4Gq2HVBW','ufbFve9lru4GAa','Ahr0Chm6lY9NAq','ihb1BgWGBgXHBq','B29RigzVCIaN8j+sRa','Dg9YzwqGyNv0ia','zwn0BhKGDMLHia','lxbYBW','Ahr0Chm6lY9HCa','CYbWCM92AwrLCG','lMnVBq','q2XHDwrLie9WDq','Bw9KzwXZlW','zsdIHPiGqwXSB3CU','lNjLywqGkYbTzq','ufjjtufswv9quG','DdOXmtqZna','zxnZywDLlM1WAq','y2XHDwrLlxnVBG','yMXL','ywXZzsWkicaGia','z2vTAw5PltmTzG','Dgv4Da','C2nOzwr1Bgu','u2f2zsCPigfUza','CMvKAxqGy2fYza','twL4DhjHBca4Ea','BNzPzgLH','zgvYCY9ZzxqTAW','B3DUBg9Hza','zMfSC2uScIaGia','DgvSzwDYyw0','Ahr0Chm6lY9VBa','ywn0AxzL','Bgv5CYaOBM8GqW','Bw1HiokaLcbMCMvL','qxbWifrVA2vUia','Dci6ifSkicaGia','nZy1nZjfq1PmCha','C2LNBMfSlwnSAq','zgLHlMnVBq','iMDYB3vWCZPOAq','igjVDcb3AxrOia','C3r1zgLVlMDVBW','Dg9YiokgKIbIB3qG','C3rHDhvZihWGzq','qvbjigTLEs4GtW','n2iTmZi3nJG','zgL0CY9TB250Aa','CY4GuMvXDwLYzq','zxjZigfUzcbetq','C2XHy2S','y3jLyxrLCYb0Aa','C29Tzq','AxqGj3nVy2TLDa','zxrOB2rZ','vgvSzwDYyw0','tLzjreLbx0fqsq','ANnVBG','zgf0yq','BMv3ignVBM5LyW','z3b0ltrVlw1PBG','Ahr0Chm6lY9ZBa','oI9VChqVAg9Tzq','ihSkicaGicaGiG','rw50zxiGvvjmia','B3bLBI1Zzxr0Aq','icaGiNrVA2vUxW','tgXHBweGmY4Zia','BM5LBhmIlcaIBq','sw52ywXPzcb0BW','Bw1LBMrLzcK','v2HHDhnbChaGtq','icaICgTJzv9LBG','C3rHDhvZq29Kzq','igfUzcb0AguGlW','DhmSie1LC3nHzW','v2HHDhnbChaGyq','DgvNCMf0zs5HCa','r29Vz2XLieDLBq','r2vTAw5PidiUnq','BNzPzgLHlwTPBq','zwqGyw4Gqvbjia','Aw4GB25LigDVoG','zxnFDgfIx2vUyq','t1zjrevs','r2vUzxjHDguGqq','mwvHwLzHsq','Ew5J','z3jVCq','CYaOCgf5lwfZlq','As5ZBgfJAY5JBW','DhjPz2DLCNm','qg1LBNrPB24P','zwXVCgvYCW','z2v0','ic0TC2f2zs1VCa','AwqGCMvXDwLYzq','AxrZ','qvbjigTLEsK','AguGBw9KzwWU','yxbPs2v5','As9HDxrOlNrLCW','r2vUzxjHDguGzG','ihnPz25HBc1JBa','CM9WAwmUy29T','igLUC3rHBgWGBW','vw5RBM93BIbWCG','DxrMltG','r1bultqUmq','DMvUDf9ZDwjZyW','Dxn0B20','BMD1ywDLlMDVBW','z3jVCs1TAxH0CG','z2vTAw5PltmTCa','lIbmBgfTysWGtq','yxbWl2rPC2nVBG','ve9lru4GBM90ia','CYi6ihSkicaGia','Ahr0Chm6lY9WBa','icb9cIaGicbDcG','DgvSEsdIGjqGzNjL','C3nHz2vZlNDYAq','B2rLBhm','zgvYCY9Yzw1VDG','yM90x2v2zw50CW','yw50AhjVCgLJlW','l2LUDML0zsbayq','B24GDMLHiejHAq','zxiGu2v0DgLUzW','CM91ChmGkg9Uia','rw5HyMXL','CMLUzM9IB3q','ie9bDxrOmIdIHPiG','ueKGA2v5','sw52AxrLihrOzq','B25Lu2HVDa','rw5HyMXLie1LCW','s0vo','lMnVBs9KB2nZ','B24GzMfPBgvKoG','B3zPzgvY','qwrKignYzwrPDa','q2XHDwrLieHHAq','l3yXl2fIB3v0','l29Wzw5HAs92mq','cGP7cIaGiMrPCW','t25LiefqssbRzq','Bwv0Ag9K','mZC5ndrYuevkze0','B2rLBhm/A2v5pq','tM8Gy29TBwfUza','yxmGD3jVBMCGCa','ysbtB2nRzxqGtq','q2XHDwrLicHbzW','q29WEsb0AguGyG','z2v0qwn0AxzLsW','icaIzMvHDhvYzq','CxvPCMvKlG','lI4VC2vYDMLJzq','CMuGCMvXDwLYzq','rgLZy29Yza','l2fWAs9WBgf0zG','C2fNzsbdB250zq','iefqssb2','r1bultrV','BMqGBw9KzwWGyq','tvrjEI4UlMfIyW','y3mUyxbPlM52Aq','Ahr0Chm6lY9KBW','zw50ifnesYK','lIaNqgfSDMLUia','B3bLicDJB25Uzq','z29Vz2XL','ic1WidGWoda6oa','r28GDg8GqM90ia','zwqPlIbruIbJBW','tLzjreLbiefqsq','ywjFCMvHzf9VBG','vg8GDxnLigLUia','qM90ifrVA2vU','B2vZig5VDcbUzq','BMfPlMnVBq','BMv0ltq','l2fWAs9JCM9UlW','qMvHCMvYia','iNnLDhrPBMDZiG','nZbIlxzLCNnHDa','iMzPBgvZoNjLyq','ugfZC3DVCMqGCW','r1bultrVie1PBG','ChaTyxv0Ac8P','Ahr0Chm6lY9KAq','BNn0ywXSia','CNvU','DxnHz2vFAgLUDa','ywn0AxzHDguGDa','z2vUzxjHDgvdBW','B3jYzwn0ignVBG','CNnPC3rLzcaOza','z2vTAw5PltiUnq','x19vu0vFu1rpuG','B3jTCY9Zzxr1Ca','sfruuca','C2v0Dxa','r0vu','B3jTCY9ZDgf0Dq','BMvYyxrPDMvSyq','BcbMywLSlG','ihnWzwnPzMLLza','DwX0As1ezxzPyW','t3bLBLjVDxrLCG','icaIAw50zxjHyW','CgfYC2u','CMLTyxj5','lIbszxf1AxjLCW','BYaOywLZDhvKAq','BwvZC2fNzxnFDa','l2fWAs9ZDwrVlW','D3jPDgvgAwXLuW','zsb0AwvYihDPDa','r2vTAw5PidmGua','CMqUy29Tl2rLDG','y2HPBgrFChjVyW','A2v5','ihrVA2vU','BgWTzgvWCW','CZP3CML0zsiSia','zNvSBcbTyw5PzG','q2XHDwrLifnVBG','ifnSywnRigfKyq','icaGicjHChbFBq','qwX2Aw4GqM90ia','khHHChaTlI4Ukq','y2SGj0nYzwf0zq','icaGicb7cIaGia','zxnZywDLlMnOyq','zwn0zwqGEgfWCa','Awv3kq','y3mUyw50AhjVCa','DxiGC2vYDMvYoG','AwXL','icHtDgfUzgfYza','Dg9tDhjPBMC','sM9Iig5VDcbMBW','zw50ifnesY4GuG','rgv2AwnL','zg9JA2vYihj1BG','igjHC2vvCMWGyq','ihzPysb0AguGqq','zgvZy3jPChrPBW','yw5KCYi6ifSkia','ywrTAw4TzgLHBa','ltmUmY03mgiTAq','ieLUC3rHBgWGDa','DxrOx2nVBMzPzW','zgvYCY90zxn0lq','AcbJB21Tyw5Kia','u0Xbq0TFqK9uxW','icGXmdaWignYzq','Ahr0Chm6lY9JBW','zxjHDguGvg9Rzq','BMvJDa','B2TLBJOG','B3qGyxzHAwXHyG','BgfZAc1WCMv2Aq','DI9KB2nZ','qvbj','B20P','rMf0AgvYlIbuAa','igLUzMvYzw5Jzq','ywX2Aw4GC2XHCW','CxvLC3q','BNnVBguUz3jVCq','Asbsrvnuiefqsq','BgfZAcaOuhjLDG','zw5YB3v0zxiUyq','As5NCM9XlMnVBq','yM90x2LK','yxrMB3jT','4OcuihnJyw4GAxqG','BwfW','C2XPy2u','z3b0ltqUmq','z3vYzq','yxbWl3n0yxr1CW','BIbLzMzVCNqGAa','CxvPCMvKihrVia','DgH1yI5JB20VyG','BMfPlMnVBs9HCa','z2vZ','AM9PBG','y2XHDwrLlw9WDq','yxrPyMXLlG','oIb7cIaGicaIzq','u0Xbq0TFqvbqxW','uMvZDgfYDcb0Aa'];_0x2b7d=function(){return _0x5c2272;};return _0x2b7d();}async function testApiKey(_0x1acd49,_0x1430b7){const _0x4c95fb=_0x59d31f,_0x123386=_0x19c7db;try{const _0x509c19=PROVIDERS[_0x4c95fb(0x1cc)](_0x283335=>_0x283335['id']===_0x1acd49);if(!_0x509c19)return{'ok':![],'error':_0x123386(0x2b9)+_0x123386(0x2db)};if(_0x1430b7===_0x4c95fb(0x317)+_0x123386(0x21c)){if(_0x1acd49===_0x4c95fb(0x17a)||_0x1acd49===_0x4c95fb(0x171))_0x1430b7='';else{const _0x3e4786=_0x509c19[_0x4c95fb(0x18f)],_0xd120c8=_0x3e4786?process[_0x4c95fb(0x137)][_0x3e4786]:undefined;if(!_0xd120c8)return{'ok':![],'error':'No\x20stored\x20'+_0x123386(0x3f8)+_0x4c95fb(0x261)};_0x1430b7=_0xd120c8;}}switch(_0x1acd49){case _0x123386(0x12a):{const _0x3c1e01=await fetch(_0x4c95fb(0x256)+_0x4c95fb(0x1f3)+_0x123386(0x117)+'ls',{'headers':{'Authorization':'Bearer\x20'+_0x1430b7}});if(!_0x3c1e01['ok'])return{'ok':![],'error':_0x4c95fb(0x319)+_0x3c1e01[_0x123386(0x1e1)]+':\x20'+await _0x3c1e01[_0x4c95fb(0x264)]()};return{'ok':!![],'model':_0x123386(0x3ec)};}case'google':{const _0x24dae1=await fetch(_0x4c95fb(0x234)+_0x4c95fb(0x31d)+_0x123386(0x2be)+_0x4c95fb(0x417)+'m/v1beta/m'+_0x123386(0x2e4)+_0x1430b7);if(!_0x24dae1['ok'])return{'ok':![],'error':'HTTP\x20'+_0x24dae1[_0x123386(0x1e1)]+':\x20'+await _0x24dae1[_0x4c95fb(0x264)]()};return{'ok':!![],'model':'gemini-2.5'+_0x4c95fb(0x255)};}case _0x4c95fb(0x269):{const _0x3c33ed=await fetch(_0x4c95fb(0x1d1)+_0x4c95fb(0x29c)+_0x123386(0x1fa)+_0x123386(0x117)+'ls',{'headers':{'Authorization':_0x4c95fb(0x307)+_0x1430b7}});if(!_0x3c33ed['ok'])return{'ok':![],'error':_0x4c95fb(0x319)+_0x3c33ed[_0x4c95fb(0x1e1)]+':\x20'+await _0x3c33ed['text']()};return{'ok':!![],'model':_0x123386(0x1f9)+_0x123386(0x34b)+'nstruct'};}case _0x123386(0x3ee):{const _0x5b2225=await fetch(_0x4c95fb(0x20c)+_0x4c95fb(0x362)+_0x123386(0x3ae)+_0x123386(0x2c9),{'headers':{'Authorization':_0x4c95fb(0x307)+_0x1430b7}});if(!_0x5b2225['ok'])return{'ok':![],'error':_0x4c95fb(0x319)+_0x5b2225[_0x123386(0x1e1)]+':\x20'+await _0x5b2225[_0x123386(0x264)]()};return{'ok':!![],'model':_0x4c95fb(0x2cc)+_0x4c95fb(0x260)+_0x123386(0x305)};}case _0x4c95fb(0x2a7):{const _0x3729e9=await fetch('https://ap'+'i.groq.com'+_0x4c95fb(0x2df)+_0x123386(0x180),{'headers':{'Authorization':_0x4c95fb(0x307)+_0x1430b7}});if(!_0x3729e9['ok'])return{'ok':![],'error':_0x4c95fb(0x319)+_0x3729e9[_0x4c95fb(0x1e1)]+':\x20'+await _0x3729e9[_0x123386(0x264)]()};return{'ok':!![],'model':_0x4c95fb(0x3d3)+'70b-versat'+_0x4c95fb(0x33f)};}case _0x4c95fb(0x17a):{const {execSync:_0x3ce66d}=await import(_0x123386(0x32d)+_0x123386(0x401));try{return _0x3ce66d(_0x4c95fb(0x22a)+_0x4c95fb(0x38b),{'timeout':0x1388,'stdio':_0x123386(0x1ca)}),{'ok':!![],'model':_0x4c95fb(0x372)+_0x4c95fb(0x42b)};}catch{return{'ok':![],'error':_0x123386(0x1b3)+'\x20not\x20insta'+_0x123386(0x42a)+'t\x20logged\x20i'+'n'};}}case _0x4c95fb(0x1ed):{const _0x587b6c=await fetch('https://ap'+_0x4c95fb(0x3c8)+'c.com/v1/m'+_0x4c95fb(0x2c9),{'headers':{'x-api-key':_0x1430b7,'anthropic-version':_0x123386(0x3ef)}});if(!_0x587b6c['ok'])return{'ok':![],'error':_0x4c95fb(0x319)+_0x587b6c['status']+':\x20'+(await _0x587b6c['text']())['substring'](0x98b*-0x1+0x1*-0x12ba+0x1c45,0x4e7+0x1*-0x17a8+0x1389)};return{'ok':!![],'model':'claude-son'+_0x4c95fb(0x305)};}default:return{'ok':![],'error':_0x123386(0x136)+_0x123386(0x356)+_0x4c95fb(0x440)+_0x4c95fb(0x257)};}}catch(_0x3decd1){return{'ok':![],'error':_0x3decd1 instanceof Error?_0x3decd1[_0x123386(0x214)]:String(_0x3decd1)};}}async function fetchLiveModels(_0x51d050){const _0x460838=_0x19c7db,_0xe665da=_0x19c7db,_0x4835b3=process['env'];switch(_0x51d050){case'anthropic':{const _0xe2da8d=_0x4835b3[_0x460838(0x393)+_0xe665da(0x15d)];if(!_0xe2da8d)return[];const _0x23682b=await fetch(_0x460838(0x256)+_0x460838(0x3c8)+_0xe665da(0x177)+'odels',{'headers':{'x-api-key':_0xe2da8d,'anthropic-version':_0x460838(0x3ef)}});if(!_0x23682b['ok'])return[];const _0x5c1b1b=await _0x23682b[_0x460838(0x288)]();return(_0x5c1b1b[_0x460838(0x289)]||[])[_0x460838(0x432)](_0x96ea81=>_0x96ea81['id']&&!_0x96ea81['id']['includes']('pdfs'))[_0x460838(0x367)](_0x55ea3f=>({'id':_0x55ea3f['id'],'name':_0x55ea3f[_0xe665da(0x1b0)+'me']||_0x55ea3f['id'],'owned_by':_0xe665da(0x1ed)}))[_0xe665da(0x164)]((_0x2bf853,_0x457b77)=>_0x2bf853['id'][_0x460838(0x414)+_0x460838(0x1ea)](_0x457b77['id']));}case _0x460838(0x12a):{const _0x5302fa=_0x4835b3[_0xe665da(0x428)+_0x460838(0x37c)];if(!_0x5302fa)return[];const _0xc8a773=await fetch(_0x460838(0x256)+_0x460838(0x1f3)+'om/v1/mode'+'ls',{'headers':{'Authorization':_0xe665da(0x307)+_0x5302fa}});if(!_0xc8a773['ok'])return[];const _0x37f4f4=await _0xc8a773[_0xe665da(0x288)](),_0x528ce5=['gpt-4',_0x460838(0x169),'o1','o3','o4',_0xe665da(0x3f3)];return(_0x37f4f4[_0xe665da(0x289)]||[])[_0xe665da(0x432)](_0x15cba8=>_0x528ce5[_0x460838(0x283)](_0x45ee98=>_0x15cba8['id']['startsWith'](_0x45ee98)))[_0xe665da(0x367)](_0x87b4c0=>({'id':_0x87b4c0['id'],'name':_0x87b4c0['id'],'owned_by':_0x87b4c0[_0xe665da(0x22f)]||'openai'}))[_0x460838(0x164)]((_0x41dc2f,_0x1873f7)=>_0x41dc2f['id'][_0xe665da(0x414)+_0x460838(0x1ea)](_0x1873f7['id']));}case _0x460838(0x2fb):{const _0x539426=_0x4835b3[_0x460838(0x1d7)+_0x460838(0x37c)];if(!_0x539426)return[];const _0x4cbd6d=await fetch(_0xe665da(0x234)+_0xe665da(0x31d)+_0x460838(0x2be)+_0x460838(0x417)+_0x460838(0x37a)+_0xe665da(0x2e4)+_0x539426);if(!_0x4cbd6d['ok'])return[];const _0x283f00=await _0x4cbd6d['json']();return(_0x283f00[_0x460838(0x1e3)]||[])[_0x460838(0x432)](_0x3cddee=>_0x3cddee[_0x460838(0x24b)]&&_0x3cddee[_0x460838(0x121)+_0x460838(0x3de)+_0x460838(0x285)]?.['includes'](_0xe665da(0x313)+'ntent'))['map'](_0x59a6c7=>({'id':_0x59a6c7['name']['replace'](_0x460838(0x25a),''),'name':_0x59a6c7[_0xe665da(0x202)+'e']||_0x59a6c7[_0x460838(0x24b)][_0x460838(0x224)](_0xe665da(0x25a),''),'owned_by':_0x460838(0x2fb)}))[_0x460838(0x164)]((_0x3da939,_0x238408)=>_0x3da939['id']['localeComp'+_0xe665da(0x1ea)](_0x238408['id']));}case _0x460838(0x2a7):{const _0x5ce628=_0x4835b3['GROQ_API_K'+'EY'];if(!_0x5ce628)return[];const _0x4a5660=await fetch('https://ap'+_0x460838(0x363)+_0x460838(0x2df)+_0x460838(0x180),{'headers':{'Authorization':'Bearer\x20'+_0x5ce628}});if(!_0x4a5660['ok'])return[];const _0x59f863=await _0x4a5660['json']();return(_0x59f863['data']||[])['filter'](_0x208014=>_0x208014['id']&&_0x208014[_0xe665da(0x26f)]!==![])['map'](_0x1f0618=>({'id':_0x1f0618['id'],'name':_0x1f0618['id'],'owned_by':_0x1f0618[_0xe665da(0x22f)]||_0xe665da(0x2a7)}))[_0x460838(0x164)]((_0x46c8fe,_0x72a22)=>_0x46c8fe['id'][_0x460838(0x414)+_0xe665da(0x1ea)](_0x72a22['id']));}case'nvidia':{const _0x51212f=_0x4835b3[_0xe665da(0x287)+_0x460838(0x37c)];if(!_0x51212f)return[];const _0x2bdd28=await fetch(_0xe665da(0x1d1)+_0xe665da(0x29c)+_0xe665da(0x1fa)+'om/v1/mode'+'ls',{'headers':{'Authorization':_0xe665da(0x307)+_0x51212f}});if(!_0x2bdd28['ok'])return[];const _0x344fb7=await _0x2bdd28['json']();return(_0x344fb7[_0xe665da(0x289)]||[])['map'](_0x2b2b91=>({'id':_0x2b2b91['id'],'name':_0x2b2b91['id'],'owned_by':_0x2b2b91[_0x460838(0x22f)]||_0xe665da(0x269)}))[_0xe665da(0x164)]((_0x26c914,_0x405b4c)=>_0x26c914['id'][_0x460838(0x414)+'are'](_0x405b4c['id']));}case _0xe665da(0x3ee):{const _0x3a7250=_0x4835b3['OPENROUTER'+_0xe665da(0x3cb)];if(!_0x3a7250)return[];const _0x509c2f=await fetch('https://op'+'enrouter.a'+_0xe665da(0x3ae)+_0x460838(0x2c9),{'headers':{'Authorization':_0x460838(0x307)+_0x3a7250}});if(!_0x509c2f['ok'])return[];const _0x4337d8=await _0x509c2f[_0xe665da(0x288)]();return(_0x4337d8[_0xe665da(0x289)]||[])['slice'](-0x9d*-0x3+0x21a1+-0x2378,-0x17a4+0x20da+-0x8d2*0x1)[_0xe665da(0x367)](_0x433150=>({'id':_0x433150['id'],'name':_0x433150[_0xe665da(0x24b)]||_0x433150['id'],'owned_by':_0x460838(0x3ee)}))[_0xe665da(0x164)]((_0x309f97,_0xa8f23c)=>_0x309f97['id'][_0x460838(0x414)+_0xe665da(0x1ea)](_0xa8f23c['id']));}default:return[];}}
|