alvin-bot 5.7.0 → 5.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +25 -31
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -174
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -583
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -86
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1902
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
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 _0x19b6b0=_0x4322,_0x2f6ba1=_0x4322;(function(_0x256766,_0x7d06f1){const _0x293af9=_0x4322,_0x3c56df=_0x4322,_0x5472d6=_0x256766();while(!![]){try{const _0x23b730=parseInt(_0x293af9(0x3c7))/(0x2151+-0x3*0x10c+-0x4*0x78b)*(-parseInt(_0x293af9(0x15a))/(-0x22a8+-0xbd3+0x2e7d))+parseInt(_0x293af9(0x1aa))/(-0x7*0x585+0x8*-0x425+-0xca*-0x5b)*(parseInt(_0x3c56df(0xf8))/(-0xabc+-0x111c+-0x4*-0x6f7))+-parseInt(_0x293af9(0x2d7))/(0x1*0x1438+0x317*-0x1+-0x111c)+parseInt(_0x3c56df(0xcb))/(0x61*-0x21+0x1e7*0x10+-0x11e9)*(-parseInt(_0x293af9(0x1a2))/(0x2*-0xa85+-0x15a8+0x2ab9))+-parseInt(_0x3c56df(0x296))/(0x1106+-0x733+-0x9cb)*(-parseInt(_0x3c56df(0x32e))/(-0x252d+0x1cd*0x9+0x1501*0x1))+-parseInt(_0x3c56df(0x2e8))/(-0x2+0x4af*0x1+-0x4a3)+parseInt(_0x3c56df(0x1b2))/(-0x3d*0xf+0x2*-0x6c7+0x1c*0x9d)*(parseInt(_0x3c56df(0x2d4))/(-0x2561+0x11b*0xd+-0x1c6*-0xd));if(_0x23b730===_0x7d06f1)break;else _0x5472d6['push'](_0x5472d6['shift']());}catch(_0x3c5f8a){_0x5472d6['push'](_0x5472d6['shift']());}}}(_0xc089,0x44d34+0x10efb*0x4+-0x1c7f4));const _0x42588e=(function(){let _0x5d0bfb=!![];return function(_0x265fae,_0x23b163){const _0x26611d=_0x5d0bfb?function(){const _0x50b69d=_0x4322;if(_0x23b163){const _0x360c14=_0x23b163[_0x50b69d(0x258)](_0x265fae,arguments);return _0x23b163=null,_0x360c14;}}:function(){};return _0x5d0bfb=![],_0x26611d;};}()),_0x4c106b=_0x42588e(this,function(){const _0x5e9545=_0x4322,_0x49b195=_0x4322;return _0x4c106b[_0x5e9545(0x37c)]()[_0x49b195(0x110)]('(((.+)+)+)'+'+$')[_0x5e9545(0x37c)]()[_0x49b195(0x3ee)+'r'](_0x4c106b)['search'](_0x49b195(0x300)+'+$');});_0x4c106b();import _0x5450d7 from'fs';function _0x4322(_0x447265,_0x41a242){_0x447265=_0x447265-(-0xe62+0x2f*0x35+0x56b);const _0x50a78a=_0xc089();let _0x19cdb6=_0x50a78a[_0x447265];if(_0x4322['dHHgkc']===undefined){var _0x46767d=function(_0x475be8){const _0x39c54e='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x55a8cb='',_0x263237='',_0x34943c=_0x55a8cb+_0x46767d;for(let _0x3aa70b=-0xfef*-0x1+0x1bf7*0x1+-0x751*0x6,_0x4ee4ba,_0x2b8523,_0x2fc182=0x11*-0x53+0x1*-0x641+0xbc4;_0x2b8523=_0x475be8['charAt'](_0x2fc182++);~_0x2b8523&&(_0x4ee4ba=_0x3aa70b%(-0x2239*0x1+0x288+-0x1fb5*-0x1)?_0x4ee4ba*(0x2e7+0x6c7+0x47*-0x22)+_0x2b8523:_0x2b8523,_0x3aa70b++%(0x2683+-0xa37*-0x3+-0x4524))?_0x55a8cb+=_0x34943c['charCodeAt'](_0x2fc182+(-0x428*-0x5+0xf*-0x13a+0x14*-0x1e))-(0x2171+0x9aa*0x1+-0x2b11)!==0xf1*-0x13+-0x1ef7+0x30da?String['fromCharCode'](0x1*-0x218+0x2*0x45a+-0x59d&_0x4ee4ba>>(-(0x5a2+-0x214d+0x1bad)*_0x3aa70b&-0x2199+0x2*0x2fe+-0x11b*-0x19)):_0x3aa70b:0xc*-0x149+0xa8*0x13+-0xfc*-0x3){_0x2b8523=_0x39c54e['indexOf'](_0x2b8523);}for(let _0x2e7706=-0xba*-0x3+0x1*0x1f7+-0x425,_0x3ebd0e=_0x55a8cb['length'];_0x2e7706<_0x3ebd0e;_0x2e7706++){_0x263237+='%'+('00'+_0x55a8cb['charCodeAt'](_0x2e7706)['toString'](0x21a4+-0xcc7*0x1+-0x47*0x4b))['slice'](-(0x208f+0x2*-0xa1c+-0xc55));}return decodeURIComponent(_0x263237);};_0x4322['ZzjbiS']=_0x46767d,_0x4322['DNojah']={},_0x4322['dHHgkc']=!![];}const _0x26d0b4=_0x50a78a[0x141b+0x17df+0xd*-0x362],_0x1f860f=_0x447265+_0x26d0b4,_0x5edd69=_0x4322['DNojah'][_0x1f860f];if(!_0x5edd69){const _0x149b90=function(_0x4e8294){this['TNpNKD']=_0x4e8294,this['HzPMSf']=[0x146*-0x1+-0x2599+-0x4dc*-0x8,-0xfaf+-0x59*-0x3a+0x1*-0x47b,0x1d74+0x20b5*0x1+0x1*-0x3e29],this['pHlRdg']=function(){return'newState';},this['HibSVT']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['iplEFr']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x149b90['prototype']['qefuRU']=function(){const _0x2748bb=new RegExp(this['HibSVT']+this['iplEFr']),_0x5a956a=_0x2748bb['test'](this['pHlRdg']['toString']())?--this['HzPMSf'][-0x2059+-0x10*-0x23a+-0x346]:--this['HzPMSf'][-0x1*-0x1abf+-0x2e5*0x5+0x1*-0xc46];return this['hnALPX'](_0x5a956a);},_0x149b90['prototype']['hnALPX']=function(_0x116d99){if(!Boolean(~_0x116d99))return _0x116d99;return this['LpNvkF'](this['TNpNKD']);},_0x149b90['prototype']['LpNvkF']=function(_0x1ae498){for(let _0x3c30ea=0x2e7+-0x1*-0x21bd+-0x24a4,_0x21aa9c=this['HzPMSf']['length'];_0x3c30ea<_0x21aa9c;_0x3c30ea++){this['HzPMSf']['push'](Math['round'](Math['random']())),_0x21aa9c=this['HzPMSf']['length'];}return _0x1ae498(this['HzPMSf'][-0x1*0x577+0x159c+-0x1025]);},new _0x149b90(_0x4322)['qefuRU'](),_0x19cdb6=_0x4322['ZzjbiS'](_0x19cdb6),_0x4322['DNojah'][_0x1f860f]=_0x19cdb6;}else _0x19cdb6=_0x5edd69;return _0x19cdb6;}import{resolve}from'path';import{execSync}from'child_process';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';function _0xc089(){const _0x58b874=['t2XSyw1HicHmBW','zgvSzxrL','CYi6ihSkicaGia','t1zjrevs','qMvHCMvYia','ywXSyMfJA3m','mte0mtK3nJrrwhnwEKe','zxiGt3bLBKfjia','B24GDMLHiejHAq','ody5mZK1tevosMTR','rw5HyMXL','l2fWCgXPy2f0Aq','CMvZDc1HCgK','yM90x2LK','B21Tyw5KoIaVyq','z3jVCq','C2vUz2vYihzPyq','Dxn0B20','y2XLyxjLzc4GuG','BcaTzYbayw50Aa','CNqU','icjYzwfJDgLVBG','r1bultrV','rNjLzsb0AwvYoG','CMLUzM9IB3q','Ahr0Chm6lY9ZBa','mJe1mJi2mffzCxjgrG','q2XPy2SGj0LUCW','iJOGwWOGicaGia','C2vJCMv0','CYbHDMfPBgfIBa','Ag9ZDa','yxbWBgLJyxrPBW','CYbVCIb1C2uGzG','qM90ifrVA2vU','BgXHBweTmY4Zlq','ugfZC3DVCMqGCW','As9RzxLZ','CMvLig1VzgvSCW','yw50AhjVCgLJlW','CgXHBIbVCIbbua','u2f2zsCPigfUza','q2XHDwrLienmsq','BMvJDgvKjYbPBG','zwqGrgv2AwnLCW','As9HDxrOlNrLCW','BNn0ywXSia','luXLDMvSifrVAW','BNnVBguUz3jVCq','Ahr0Chm6lY9HCa','kcGOlISPkYKRkq','BgXHBweGkg1HyW','uMvNAxn0zxiGEq','u2vSzI1JAgf0ia','BguGzM9YihrOAq','z3b0ltqUmq','BhzPBIbZDgf0Dq','CM9WAwmTywKVyW','B3qGDg9Rzw4GAa','y2qGiG','z2v0','BhLFzw5HyMXLza','BgXHBweTmY4Xlq','z2uUAw0IlcaIBq','mtiZndu2oKfcqW','BwvKAxvTFgHPzW','DgLJywXSEsaOBa','CYikicaGicaGxq','tLzjreLbiefqsq','C2GGDMLHieDVBW','BcbMywLSlG','BM90ihnLDa','y2XHDwrLlw9WDq','iMnOyw5UzwXZoG','tsbuue0','u2LNBMfSie51Bq','CgfYC2u','CxvPCMvKlG','B2TLBIbPBNrVia','lI4PigLUDg8GuW','CgrMCW','AYaNvgvZDcbdBW','CMvZB2X2zq','t0TftIbIzwXVDW','x2vZy2fWzsi6ia','yMXLzci6ihrYDq','r2vTAw5PidiUnq','AxH0CMfSlcbhzq','4OAsifbYAxzPBgvN','iJOGiM5LDYb8ia','BI94lxD3DY1MBW','lMnVBq','zguTreu','B2rLicHUBYbWDq','icaGicb7cIaGia','zxf1AxjLza','nJeZohfTEKPUEa','iJOGDhj1zsWkia','khHHChaTlI4Ukq','ic9ZDgf0DxmSia','qKvs','z3jVCs1TAxH0CG','reLtq09srf9utW','C2v0sgvHzgvY','zxjZigfUzcbetq','CM90yxrPB25Fzq','icaICgTJzv9LBG','q3jLyxrLigfJyW','lwnSAs1Yzxn0lq','AM9PBG','B3j0lcaVAgvSCa','Bw9VBNnOB3rHAq','yxbPl3yXmc91CW','yxjL','BMqGysbTzxnZyq','zgLZy29Yza','ruXgx0niqvrFtW','B2vZig5VDcbUzq','BgqGC2vLicDayq','ChmGyw5KignSAq','zxmGDgHLihrLBq','z3jHDgLVBIb2Aq','zsbIB3qGke1HAq','zwXVCgvYCW','uK9wsurfuLm','AgvUiebTzw50Aq','zsbZAwDUywWTyW','icaGiNrVA2vUxW','CY4GuMvXDwLYzq','sfruuca','kIOQkG','BwL4DhjHBc04Ea','DgL2Axr5iJOGEW','s0voig5VDcbZzq','BMvSCYWGyw5Kia','l25LDYWGl2vMzG','icHjrdOG','ihDLyxrOzxiGAq','DgfSBcbbChaG4OAs','BNqGu0rl','zsbMB3iGzNjLzq','BMvYyxrPDMvSyq','DgH1yI5JB20VyG','z3vYzq','D2vIlxvP','ifjLC3rHCNqGyG','C29Tzq','AhXTyxGGFcbOzq','rw50zxiGvvjmia','q3jLyxrLigfUia','yxrMB3jTlM9Wzq','lM9YzY9IB3q','yxrOzxiGB24Gva','Aw5NCYdIHPiGqMfZ','C3rYDwn0Aw9UCW','Ahr0Chm6lY9PBG','igeGC2vWyxjHDa','uefusa','zMLUzeLUzgv4','ywjFCMvHzf9VBG','zw52vMfYCW','BMfIBgvKiJOGzG','oI9VChqVAg9Tzq','zciScIaGicaGia','rNvSBcb0B29Sia','tgXHBweGmY4Zia','kYbTzxnZywDLCW','yw5KCYi6ifSkia','Aw4GkgjYB3DZzq','CM8GkfbYzxzPzq','DMvYAwzPy2f0Aq','CM91ChmGkg9Uia','y2XHDwrLic0TDG','B3jTCY9JB25MAq','Dg9tDhjPBMC','BsikicaGicaGxq','BgfZAcaOuhjLDG','ywiGkhjLCgXHyW','CMvZDwX0','CMvLiefqssbRzq','r29Vz2XLieDLBq','vw5RBM93BIbWCG','z2vTAw5PltiUnq','CgvUquKTy29TCa','lMDVB2DSzs5Kzq','BgfTys5JB20VBa','zxjL','yxbPs2v5rw52','qK9ux1rps0voia','vw5RBM93BIbWBa','yY5JB20VDJeVBq','z2vZ','icaIAw50zxjHyW','q2XPy2SGq3jLyq','DgvSzwDYyw0','y2XHDwrLlwHHAq','zxjYB3i','ieLUC3rHBgWGDa','uhjVDMLKzxiGza','D2HHDcDZihrOzq','As5ZBgfJAY5JBW','icaGiM1LC3nHzW','igjVDcb0BYb5BW','icH0zwfTx2LKoG','B3jTCY9ZDgf0Dq','CgXHEv9PBMzVCG','yxbP','zwvKzwqPlIbetq','C2v0','C3bSAxq','zgv2zwXVCgvYCW','Bgv5CYaOBM8GqW','rKfmtejbq0TFua','z2XLyxbPCY5JBW','A2v5','ienVChKGDgHLia','y2HHBM5LBhm6ia','yxrMB3jT','nZbIlxzLCNnHDa','rgLZy29Yza','y29TBwfUzhmIla','B25Lu2HVDa','uhvSBcbHig1Vza','ywn0AxzHDguGDa','icGXmdaWignYzq','B3bLBIb0AguGyq','zw52','y3mUyxbPlM52Aq','CM9WAwmUy29T','BhmGB24GEw91CG','zxn0yxj0ihjLCq','C3rHCNrZv2L0Aa','iIaMjIbUCg0GAq','BMaGC2XHC2GGyW','Bw9KzwXZlG','j0jVDcbvC2vYia','oIb7cIaGicaIzq','Bwv0Ag9K','khHVEgiTlI4Ukq','vc00lJeSig8ZlW','C2XPy2u','B3bLBNjVDxrLCG','EgfWCc0UlI4','yxbWl2rPC2nVBG','zwfYigjLBg93ia','z19KzxbSB3LFzq','cIaGicb9laOGia','ic1WidGWoda6oa','zwqPlIbruIbJBW','mJe1svrKyu15','l2fWAs9JCM9UlW','DhmSie1LC3nHzW','zxjHDguGvg9Rzq','Ahr0Chm6lY9VBa','DwLYzwqGzM9Yia','y3rLzcbcB3qGva','C3DPDgnOvg8','B24GAxqGkguUzW','t1bftKfjx0fqsq','qhnSywnRl2jVBa','u2f2zsbIB3rOia','zgfWDgvYig5VDa','Bg9JywXLq29TCa','BNmGAw4Gy2HHBG','DgvNCMf0zs5HCa','DhLWzq','zxiU','q2XHDwrLie9WDq','q2XPy2SGj1jLCW','zNvSBcbTyw5PzG','C2fNzsbdB250zq','yxrPy2fSBhKGBW','zMLNihbYzs13Aq','B3qGyxzHAwXHyG','ywrTAw4TzgLHBa','Dw5RBM93BG','z3b0ltrV','CM0TDxjSzw5JBW','igLUC3rHBgWGBW','DxiGC2vYDMvYoG','zwXVDYbPBNrVia','ytmUmG','BxmVC2LNBMfSlG','v2HHDhnbChaGyq','Ew5J','y3jLyxrLCYb0Aa','B3qGyw5KigzVBa','BMvJDa','y29UC3rYDwn0BW','BMv4Dfj1BKf0','Bs9HChbZ','t3bLBLjVDxrLCG','DcbnB2rLihDPBa','sw52AxrLihrOzq','BgWTzgvWCW','r2vTAw5PidmGua','u2XHy2SGD29YAW','Awv3kq','lIaNqgfSDMLUia','tLzjreLbie5jtq','zgvKihDPDgGG','v0HbvfnbufbFqq','zxf1AxjLCYbdBa','ndi1ndK0mKfZwuH6yG','zxHPC3rZu3LUyW','iMjVDf91C2vYiG','BweG4OcuigfSBcb2','zMLYC3rFBMfTzq','s2v5ihrLC3qGBG','zw50Aw9UCZPYzq','vgHLignVBM5LyW','ogiTAw5ZDgfUDa','Cc5QCW','Aw5NCYdIHPiGsw5Z','yMvYBMHHCMqVCW','tLzjreLbx0fqsq','AwyGBMvLzgvKkq','ywWTy2XPifjfuW','uMvWBhKGAw4GzW','x19vu0vFu1rpuG','z2v0qwn0AxzLsW','zw52s2v5','igzPCNn0ihn0yq','BhzPBIbVBIa8vW','B3jRC3bHy2u+jW','BYaOywLZDhvKAq','BwvZC2fNzq','ve9lru4','y2HPBgrFChjVyW','cGP7cIaGiMrPCW','DMvYAwz5','r28GDg8GqM90ia','lNjLywqGkYbTzq','igfUzcbJBgLJAW','DxnYl2XVy2fSlW','C2vYieLeoIbtzq','B3vUDcbVBIbVCa','ve9lru4GyMvSBW','BgvUz3rO','lurfrI4UlG','mdGWigjIzxjUAa','As9KB2nZ','AwmUy29Tl2vUlW','DxjLza','zgvZy3jPChrPBW','Bg93ihrOzsbPBG','Ahr0Chm6lY9IDq','BNzPzgLHlwTPBq','ndy3mtzhwKPKr0W','y29UBMvJDgvK','CMvKAxqGy2fYza','C2LKzwjHCIWGyW','igXVywrLza','l3yXl2fIB3v0','DgHLiePtt04GDa','zxiGu2v0DgLUzW','z2vUzxjHDgvdBW','BMqGBw9KzwWGyq','x0Tfwq','r28GDg8Gu2v0Da','lxbYBW','s2LTAsblmI41','CMLUzW','zMfSC2ukicaGia','B3qP','As5HBNrOCM9WAq','zg9JCY9JBgf1za','BM90x2nVBMzPzW','zwXLz3jHBq','B3bLBMfPlwnVBq','BZmTBwLUAq','y2XHDwrLlxnKAW','C2vHCMnO','C2uGAw1TzwrPyq','odKW','y2XHDwrLlxnVBG','vg8GDxnLigLUia','u2f2zwqU','lwzSyxnO','BgLJAYaNtwvZCW','sw52ywXPzcb0BW','zgLZCgXHEu5HBq','C3rHDhvZ','ugfZC3DVCMqGCG','As5UDMLKAweUyW','iKfSDMLUiIWGiG','ie9bDxrOmIdIHPiG','CYdIHPiGqvbjieTL','yw1HlMnVBs9KBW','AgvHzgvYCW','zwn0BhKGDMLHia','vwX0CMeTzMfZDa','CYaOCgf5lwfZlq','zxnZywDLlMnOyq','icaGicjTzxnZyq','B2nRzxqGtw9Kzq','C2LNBMfSlwnSAq','BNnVBguUyw50Aa','zguGC2nHBIbVBG','CMTZCgfJzs4','l2fWAs9ZA2LSBa','Ahr0Chm6lY9Nzq','zgfZAgjVyxjK','ihnWzwnPzMLLza','BMv3lcaVywX2Aq','yxvKzsbdteKGBa','iNnLDhrPBMDZiG','BMD1ywDLlMDVBW','CM9WAwmUy29TlW','BZmGtwLUAq','Ahr0CdOVl2XVyW','Eg94yI0UlI4','ihb1BgWGBgXHBq','icHtDgfUzgfYza','yMfZzvvYBa','As1RzxLZ','A2v5lcbUyw1Lla','DMvUDf9ZDwjZyW','Bw9KzwXZ','CMLTyxj5','Ahr0Chm6lY9KBW','zMLUza','B3bLicDJB25Uzq','ywjSzs4','zxHLyW','D3jPDgvgAwXLuW','CY00lty','DguNlcbJBgLJAW','Aw4GB25LigDVoG','D2HHDhnHCha','BYbxB3jRC3bHyW','q2XHDwrLiefNzq','Bs5QCW','ig1Hy2HPBMuUia','BwfW','zgvYCY9ZzxqTAW','ChaGAw4GDgHLia','igfWCcbTyw5PzG','y2fSkq','zxnZywDLlMDYBW','DxnLihzPysbbzW','zwW6ig9SBgfTyq','ufjjtufswv9quG','BMDZ','tM8Gy29TBwfUza','yxbWl3n0yxr1CW','nJGXmg5uENLzEa','r1bultqUmq','BhaIlaOGicaGia','zMzVCNqGBg93Fa','r1bultrVlcbhua','uMvZDgfYDcb0Aa','rw5HyMXLie1LCW','B3jTCY9PBNn0yq','BMfTzq','t3bLBIbhB29NBa','ihSkicaGicaGiG','y2TLDcbnB2rLla','icaIy29TBwfUza','CgXHDguPlIbuAa','y2XHDwrLigXVzW','r2vTAw5PidmGrG','As5NCM9XlMnVBq','B3jYzwn0ignVBG','y3mUyw50AhjVCa','y3rZigf1Dg9Tyq','DhjPz2DLCNm','zwqIoIb0CNvLia','DgLVBI4','u0Xbq0TFqvbqxW','z29Vz2XL','Bwf0Aw9UiJOGEW','vvjmieDLBMvYyq','yxbWBhKGy2HHBG','yxrHl3DOyxrZyq','zgvK','yw5Kig51BwjLCG','lsKG4OcuifnVy2TL','zMfSC2uScIaGia','ufbFve9lru4GAa','BtPOAxn0B3j5iG','Bw9KzwW','l21VzgvSCW','AwTLEq','BZqGyw5Kig90Aa','rgv2AwnL','Ahr0Chm6lY9WBa','BIbLzMzVCNqGAa','BweTmY4ZltCWyG','yw50AhjVCgLJ','DxnLCM5HBwu','Ahr0Chm6lY9KAq','B2TLBJOG','Dgv4Da','nZbc','Dwukicb9laOGia','ChjPB3jPDhK','u3rHCNqGC2LNBG','ltmUms04yG','C2vJDxjPDhK','qg1LBNrPB24P','r2vUzxjHDguGzG','zsb9laOGicaGiG','DgfYDcbIB3qNia','B3bLBI1Zzxr0Aq','zgf0yq','DcbSB2DNzwqGAq','vgHLiffsignVza','yxrPyMXLlG','iefqssb2','Dci6ifSkicaGia','C2nVCMqUy29TlW','ywXOB3n0oJGWoa','BNbTigLUC3rHBa','ihjLywnOywjSzq','yMXPyYbvuKWGBG','BxmVD2HHDhnHCa','y2HHDgDWDa','n0X3seLUBq','DxbKyxrL','CYbKAxnJB3jKlG','C2nVCgvZiJOGEW','zgvYCY9Yzw1VDG','BNbTugfJA2fNzq','CM9Y','B3bLCYWGzxzLBG','mJa0sxvlwuPq','C3rVCNKIlcaIAq','tM8GzgvWzw5Kzq','DxnHz2vFAgLUDa','Ahr0CdOVlW','DgvHBq','CYWGC2HLBgWGyW','t3bLBKfj','mtfwzu5sChG','CYWGqg1LBNrPBW','ugfZDguGDgHLia','Dw5K','ue9tva','lIbmBgfTysWGtq','z2XLigfIB3zLkq','yxv0Ac50zxn0oG','Dg9mB2nHBgvtDa','DxnLoIbYzwfKlW','zxzLCNK','iJOGEWOGicaGiG','x1vstcbUB3qGCW','s0vo','Cgf0AwjSzq','CMuGCMvXDwLYzq','DgLVBMfSidi+jG','C2nOzwr1Bgu','iokAOo+4JYbttefds19b','zg9JA2vYihj1BG','B2DPBIaOtwf4ia','zsdIHPiGqwXSB3CU','AgLZDg9YEsiSia','AguGC2XHC2GGyW','BhzPBIbHBMqGDa','zs1JDxn0B20','zw50ifnesYK','ide1ifjqtsWGmq','B3DUzwrFyNK','yxjKl3nPz25HBa','ChvZAa','v2HHDhnbCha','z3b0ltrVlw1PBG','CY9ZA2LSBhmUAG','lMnVBs9KB2nZ','ihzPysb0AguGqq','As9HCgKVDJeVBq','BMfPlMnVBs9HCa','BNzPzgLH','EgfWCc0UlI4GDa','yMvY','rvjt','z3b0ltqUms1TAq','icaGFsWkicaGia','u0LhtKfmx0fqsq','ihrOzsbSB2DZkq','r1bultrVie1PBG','icaGiMfWCf9Tzq','AweGB25Liefqsq','iMHVBwvFDgfIxW','zw5HyMXLzci6ia','qwX2Aw4Iih0ScG','BIbczxjSAw4/jW','zwqGyw4Gqvbjia','ie5LDYbbChaNia','BM5LBhmIlcaIBq','oIb7icjKAxnWBa','Ahr0Chm6lY90lG','DwX0As1ezxzPyW','ig9Uia','B2rLBhm','v0HbvfnbufbFrq','BMv3ignVBM5LyW','C3r1zgLVlMDVBW','t3bLBIbaqM90rG','AwDOlcaVywX2Aq','y2HHBM5LBc4','vcbbueKGkerVyW','ifbYBW','BMfPlMnVBs9KBW','B3DUBg9Hza','AxqGj3nVy2TLDa','icaGicjHChbFBq','ig5LzwrLzcWGCG','Ahr0Chm6lY9HAq','CMvHzezPBgvtEq','l2fWAs9JCM9U','C3vWCg9YDgvKrW','otG3nJu0mZiX','lIbpCIb1C2uGDa','B25Z','y3jLyxrL','qM90ia','BgKGy29UDgfPBG','qvbjx0Tfwq','l29Wzw5HAs92mq','C3rYAw5NAwz5','B29RigzVCIaN8j+sRa','ywnRlMnVBs9HCa','C3rHDhvZq29Kzq','D25SB2fK','CNvU','DgLLCIbHDMfPBa','zgLZy29Yzc5QCW','icDtyxzLjW','u2LNBMfS','zsbKzwzHDwX0ia','zsbbssbtDhvKAq','u0LhtKfmx05vtq','AxmGC2v0CYbZyW','AwXKlM52AwrPyq','Ahr0Chm6lY9NAq','r2vUzxjHDguGqq','y29UBMvJDgLVBG','FsWkicaGicjVCG','B2XSyw1H','AxrZ','uMvZDgfYDcbYzq','A2vU','teXpv19etvm','qxbWifrVA2vUia','DgfYz2v0','rgLZy29YzcbIBW','igfSBcb0AguGyW','y2f0zwDVCNK','Ahr0Chm6lY9JBW','CMvXDwLYzxmGyq','n0iGkeDYB3eP','icaGicaIy29TBq','ihDPBgWGzMfPBa','rurFxW','qvbjigTLEsK','ltmUmY03mgiTAq','iezSyxnO','DcbMB3iGC2vYDG','r1jpuv9bueLFsW','zhKGDg8GDxnLia','qwX2Aw4GyM90ia','C2fNzxm','Asbsrvnuiefqsq','CIbHDxrOig9Yia','zMLSDgvY','igfUzcbSAwDODa','qwrKignYzwrPDa','ANmU','z2vTAw5PltmTCa','zgLZy29UBMvJDa','sw5ZDgfSBcbpBa','Ahr0Chm6lY9VCa','Bw9KzwXZlW','qvbjihjLC3bVBG','BxmVzgLZy29Yza','icaGiNnOB3vSza','ihrOzw4Gy2XPyW','zw5ZiokgKIaNr2vU','igfUzcb0AguGlW','CMvWBgfJzq','C29YDa','qM90ifrVA2vUia','q2XHDwrLicHbzW','B2rLBhm/A2v5pq','zw5YB3v0zxiUyq','CMv2B2TL','BMv0ltq','y3rPB25ZoNDYAq','Axb0Aw9UiJOGiG','DMLUiIWkicaGia','Dw5Zig9MzMXPBG','icjPC19LBMfIBa','uNvUCYbHDxrVBq','DxrOx2nVBMzPzW','l2fWAs9WBgf0zG','As50zwXLz3jHBq','ywjSzwqIoIb0CG','DxrMltG','l2fWAs9ZDwrVlW','yxbWBhK','qu5usfjpueLdxW','DxnLCG','yw5KiJOGiI9HBa','z2XLlMnVBs9HCa','B3iGChjPDMLSzq','ig5VDcbPBNn0yq','A2vUiokgKIbdB3b5','t1bftLjpvvrfuG','lI4VCgXHDgzVCG','C2LNBMfS','BY5NB29NBguUyW','tM8GqvbjigTLEq','A3uTnc01','vvjm','DguUifnSywnRia','zsbJB25Uzwn0Aq','AwmGsw5MB3jTyq','B3jTCY90zxn0lq','D3jPDguGzMLSzq','DhnbChaGkhrVzW','ihnPz25HBc1JBa','qwX2Aw4GqM90ia','BNrLBNq','Ew91lwDVksbVCG','Dg9Y','C2v0Dxa','zsaOy2XPy2SGjW','B24GzMfPBgvKoG','zxrOB2rZ','ueKGA2v5ihvUza','zgLZy3jPBwLUyq','BwvZC2fNAw5Nia','ywXZzsWkicaGia','igLUzMvYzw5Jzq','Dg9YiokgKIbIB3qG','CM1tEw5J','x0fqsv9lrvK','CYa0lJy','l2fWAs9WCM92Aq','lI4VC2vYDMLJzq','BgfZDfj1BKf0','lMnVBsaOBM8GyW','yM90x2v2zw50CW','x1vsta','y2TLDhmVyMfPBa','B21Tyw5KCYWGyG','zxnZ','C3rHDhvZihWGzq','yxbPs2v5','iMzPBgvZoNjLyq','qK9ux1rps0vo','qvbjigTLEs4GtW','iMfWCf9OB21LiG','r09pr0Xfx0fqsq','EgfWCc0','mtiZndu2nZG5la','AcbJB21Tyw5Kia','B20VDJeVBw9Kzq','qvbj','tKfcteve','CMLWDgLVBNmIoG','nJe4ngXmrM1wuW','As5VCgvUywKUyW','t25LiefqssbRzq','CxvPCMvKihrVia','zxnZywDLlM1WAq','zNjVBuvUDhjPzq','icaGicaGiMzPBa','sM9Iig5VDcbMBW','D2vI','AwXL','z2vTAw5PltmTzG','DdOXmtqZna','zxiGsurZ','qhDOAxnRzxLZBW','B3qGDMLHiejVDa','C2uGEw91CIb3BW','Bgf1zguTy29Kzq','zxm6D3jPDguIla','B3zPzgvY','yMXL','B3bLBMfP','C2vHCMnOugfYyq','B25SEsaOCMvJBW','BgLZDefSBa','u0Xbq0TFqK9uxW','zxmNlIboyw1Lia','ueKGA2v5','sw4Gu2XHy2S6ia','Dhj1zq','Bs92mwjLDgeVBq','vgvSzwDYyw0','CMvKlG','CYbMCMvLicHmBa','BwvZC2fNzxnFDa','yxmGD3jVBMCGCa','z2XLiefjifn0Dq','BgfZAc1WCMv2Aq','DxbZiIWkicaGia','CM8TChjLDMLLDW','zxLZ','AguGBMv3igTLEq','CxvLC3q','sw52ywXPzcbYzq','Aw52AxrLihrOzq','mJaYmY0WnI0Wmq','ywDLCYCGDgfIla','q2XHDwrLifnVBG','ANnVBG','zwn0zwqGEgfWCa','BgXHBweZlJi','zw5K','r1bultqUmsbnAq','CYWGl2fSDMLUia','As1RmI41','Dg9Nz2XL','C3bHy2uGAw50zq'];_0xc089=function(){return _0x58b874;};return _0xc089();}import{CUSTOM_MODELS as _0x22756c,BOT_ROOT,WHATSAPP_AUTH}from'../paths.js';import{readEnv,writeEnvVar,removeEnvVar}from'../services/env-file.js';function loadCustomModels(){const _0x803910=_0x4322,_0x538acc=_0x4322;try{return JSON['parse'](_0x5450d7[_0x803910(0x1fd)+'nc'](_0x22756c,_0x538acc(0x256)));}catch{return[];}}function saveCustomModels(_0x1379e4){const _0x531068=_0x4322,_0x2a0922=_0x4322;_0x5450d7[_0x531068(0x145)+_0x531068(0x3ea)](_0x22756c,JSON[_0x2a0922(0x208)](_0x1379e4,null,-0x142c+0x11*-0x53+0x1*0x19b1));}const PLATFORMS=[{'id':_0x19b6b0(0x390),'name':_0x19b6b0(0x2b4),'icon':'📱','description':'Telegram\x20B'+_0x2f6ba1(0x2a4)+'Father.\x20Th'+_0x19b6b0(0x212)+_0x2f6ba1(0x278)+_0x19b6b0(0x1f4),'envVars':[{'key':'BOT_TOKEN','label':_0x19b6b0(0x2f0),'placeholder':_0x2f6ba1(0x30e)+_0x19b6b0(0xef),'secret':!![]},{'key':'ALLOWED_US'+_0x2f6ba1(0x1db),'label':'Allowed\x20Us'+_0x19b6b0(0x2a2),'placeholder':_0x19b6b0(0x290)+_0x19b6b0(0x200)}],'setupUrl':_0x19b6b0(0x1eb)+'me/BotFath'+'er','setupSteps':[_0x19b6b0(0x1f2)+_0x2f6ba1(0x366)+_0x2f6ba1(0x10c),'Send\x20/newb'+_0x2f6ba1(0x3ec)+_0x19b6b0(0xf5)+_0x2f6ba1(0x368),'Copy\x20the\x20b'+_0x2f6ba1(0x308)+_0x2f6ba1(0x388),'For\x20your\x20U'+_0x19b6b0(0xeb)+_0x19b6b0(0x340)+'ge\x20to\x20@use'+_0x2f6ba1(0x2e6)]},{'id':_0x19b6b0(0x341),'name':_0x2f6ba1(0x3a9),'icon':'🎮','description':_0x2f6ba1(0x222)+_0x2f6ba1(0x22e)+_0x19b6b0(0x336)+_0x19b6b0(0x34e)+_0x2f6ba1(0x1a4)+_0x19b6b0(0x238),'envVars':[{'key':'DISCORD_TO'+_0x19b6b0(0x1bf),'label':_0x2f6ba1(0x2f0),'placeholder':'MTIz...abc','secret':!![]}],'npmPackages':[_0x2f6ba1(0x20f)],'setupUrl':_0x2f6ba1(0x187)+_0x19b6b0(0x19b)+_0x19b6b0(0x3a0)+_0x2f6ba1(0x2d9)+_0x2f6ba1(0x202),'setupSteps':[_0x19b6b0(0x363)+'Applicatio'+'n\x20on\x20disco'+'rd.com/dev'+_0x2f6ba1(0x349),_0x2f6ba1(0xe7)+'→\x20Reset\x20To'+_0x2f6ba1(0x25f)+'\x20token',_0x2f6ba1(0x160)+_0x2f6ba1(0x3dc)+'nt\x20Intent\x20'+'under\x20Bot\x20'+_0x2f6ba1(0x326)+'ed\x20Intents',_0x19b6b0(0x3f3)+_0x19b6b0(0x398)+_0x19b6b0(0x3e5)+_0x2f6ba1(0x11e)+_0x2f6ba1(0x174)+_0x2f6ba1(0x27b)+_0x2f6ba1(0x374)+_0x2f6ba1(0xe8)+'ssages.wri'+'te']},{'id':_0x2f6ba1(0x149),'name':_0x2f6ba1(0x1d1),'icon':'💬','description':'WhatsApp\x20M'+_0x2f6ba1(0x1ec)+_0x19b6b0(0x268)+_0x2f6ba1(0x2d6)+_0x19b6b0(0x3a1)+'hrome\x20need'+_0x2f6ba1(0x3c6)+_0x19b6b0(0x12a)+_0x2f6ba1(0xde)+_0x2f6ba1(0x2e2),'envVars':[{'key':_0x19b6b0(0x1ef)+'NABLED','label':_0x19b6b0(0x2d8),'placeholder':'true','type':'toggle'},{'key':'WHATSAPP_S'+_0x19b6b0(0x342)+'NLY','label':_0x19b6b0(0x303)+_0x2f6ba1(0x2ac)+'mmended)','placeholder':_0x2f6ba1(0x2b2),'type':_0x2f6ba1(0x2cc)},{'key':'WHATSAPP_A'+'LLOW_GROUP'+'S','label':_0x19b6b0(0xda)+_0x19b6b0(0x379)+_0x19b6b0(0x190),'placeholder':'','type':_0x19b6b0(0x2cc)},{'key':_0x19b6b0(0xc9)+_0x19b6b0(0x21f),'label':'Reply\x20to\x20p'+'rivate\x20mes'+_0x19b6b0(0x232),'placeholder':'','type':_0x2f6ba1(0x2cc)}],'npmPackages':[_0x2f6ba1(0x2a3)+_0x2f6ba1(0x285)+_0x19b6b0(0x2bd)],'setupSteps':[_0x2f6ba1(0x2e9)+'tall\x20Depen'+'dencies\x27\x20('+_0x2f6ba1(0xd8),'Enable\x20Wha'+_0x19b6b0(0x26c)+_0x2f6ba1(0x1b8)+_0x19b6b0(0xe9)+_0x19b6b0(0x210),_0x2f6ba1(0x15f)+_0x19b6b0(0x348)+'ntenance\x20→'+_0x19b6b0(0x35f)+_0x2f6ba1(0x108),_0x19b6b0(0x197)+'e\x20will\x20app'+_0x19b6b0(0x3c2)+'—\x20scan\x20it\x20'+'with\x20Whats'+'App\x20→\x20Link'+_0x19b6b0(0x2fa)+'\x20→\x20Link\x20a\x20'+_0x19b6b0(0x181),_0x19b6b0(0xd2)+'tion\x20is\x20pe'+'rsisted\x20(d'+_0x19b6b0(0x176)+'pp-auth/)']},{'id':'slack','name':'Slack','icon':'💼','description':_0x2f6ba1(0xc4)+_0x19b6b0(0x2cd)+_0x2f6ba1(0x347)+'a\x20Socket\x20M'+_0x19b6b0(0x32b)+_0x19b6b0(0x19f)+_0x19b6b0(0x39d)+_0x19b6b0(0x1b3)+_0x19b6b0(0x3d5)+_0x2f6ba1(0x354)+'the\x20`/alvi'+_0x19b6b0(0x3b7)+'ommand\x20for'+_0x2f6ba1(0x331)+_0x19b6b0(0x355)+_0x2f6ba1(0x33c)+'\x20(v4.13.2+'+').','envVars':[{'key':'SLACK_BOT_'+_0x2f6ba1(0xe3),'label':_0x2f6ba1(0x246)+_0x2f6ba1(0x3bc),'placeholder':_0x2f6ba1(0x137),'secret':!![]},{'key':'SLACK_APP_'+_0x19b6b0(0xe3),'label':_0x19b6b0(0x220)+_0x2f6ba1(0x330),'placeholder':_0x2f6ba1(0x3c0),'secret':!![]}],'npmPackages':[_0x19b6b0(0x3d1)+'t'],'setupUrl':_0x19b6b0(0x2ff)+_0x19b6b0(0x396)+_0x19b6b0(0x3f0),'setupSteps':['Go\x20to\x20http'+'s://api.sl'+_0x19b6b0(0x20a)+_0x2f6ba1(0x345)+'ck\x20\x27Create'+_0x19b6b0(0x1e8)+'→\x20\x27From\x20an'+_0x19b6b0(0x151)+'est\x27.\x20Choo'+_0x19b6b0(0x2a5)+_0x19b6b0(0x12b),_0x19b6b0(0x1b4)+_0x19b6b0(0x3db)+'est\x20JSON\x20b'+_0x2f6ba1(0x3e6)+_0x2f6ba1(0xfe)+_0x2f6ba1(0x37f)+_0x2f6ba1(0x346)+_0x19b6b0(0x167)+_0x19b6b0(0x215)+_0x2f6ba1(0x1a9)+_0x2f6ba1(0x3c9)+'es\x20Tab,\x20So'+_0x2f6ba1(0x165)+_0x2f6ba1(0x243)+'alvin\x20slas'+_0x2f6ba1(0x291)+_0x2f6ba1(0x148)+_0x19b6b0(0xe5)+_0x2f6ba1(0x39b)+_0x2f6ba1(0x173)+'\x20\x22name\x22:\x20\x22'+_0x19b6b0(0x1e5)+'\x20\x20\x22feature'+_0x2f6ba1(0x2d0)+_0x19b6b0(0x28d)+':\x20{\x0a\x20\x20\x20\x20\x20\x20'+_0x2f6ba1(0x1e3)+_0x2f6ba1(0x1e4)+_0x2f6ba1(0x17a)+_0x2f6ba1(0x397)+'es_tab_ena'+_0x2f6ba1(0x323)+'e,\x0a\x20\x20\x20\x20\x20\x20\x22'+_0x19b6b0(0x2b7)+_0x2f6ba1(0x36d)+_0x19b6b0(0x30b)+'\x22:\x20false\x0a\x20'+_0x19b6b0(0x1dd)+_0x19b6b0(0xcd)+_0x2f6ba1(0x1ea)+'ay_name\x22:\x20'+_0x19b6b0(0x11d)+'always_onl'+'ine\x22:\x20fals'+_0x2f6ba1(0x192)+'slash_comm'+_0x19b6b0(0x375)+_0x2f6ba1(0x32c)+_0x2f6ba1(0x228)+_0x2f6ba1(0x25b)+_0x19b6b0(0x24e)+'\x20\x20\x20\x20\x22descr'+_0x2f6ba1(0x24d)+_0x2f6ba1(0x231)+_0x19b6b0(0x3aa)+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x22'+_0x2f6ba1(0x1ad)+_0x19b6b0(0x327)+_0x19b6b0(0x288)+_0x2f6ba1(0x15d)+_0x2f6ba1(0x30f)+_0x19b6b0(0x361)+_0x2f6ba1(0x15c)+_0x2f6ba1(0x240)+_0x2f6ba1(0x322)+_0x19b6b0(0x107)+'\x20\x20}\x0a\x20\x20\x20\x20]\x0a'+'\x20\x20},\x0a\x20\x20\x22oa'+_0x19b6b0(0x252)+_0x2f6ba1(0x1bd)+_0x19b6b0(0x1a5)+'\x0a\x20\x20\x20\x20\x20\x20\x22bo'+_0x19b6b0(0x19a)+_0x19b6b0(0x1fa)+_0x2f6ba1(0xd1)+'ad\x22,\x20\x22mpim'+':read\x22,\x20\x22c'+'hat:write\x22'+',\x0a\x20\x20\x20\x20\x20\x20\x20\x20'+_0x19b6b0(0x317)+_0x19b6b0(0x1c8)+'\x22groups:hi'+_0x2f6ba1(0x1ab)+_0x2f6ba1(0x17c)+',\x20\x22mpim:hi'+'story\x22,\x0a\x20\x20'+_0x19b6b0(0x29c)+_0x19b6b0(0x2a7)+_0x2f6ba1(0x2e3)+'s:write\x22,\x20'+_0x19b6b0(0x28a)+_0x19b6b0(0x371)+_0x19b6b0(0x166)+_0x2f6ba1(0x311)+_0x2f6ba1(0x3c4)+_0x19b6b0(0x338)+_0x19b6b0(0x255)+_0x2f6ba1(0x18b)+_0x2f6ba1(0x132)+_0x2f6ba1(0x3ba)+(_0x2f6ba1(0x13d)+_0x19b6b0(0x295)+_0x2f6ba1(0x164)+_0x19b6b0(0x283)+_0x2f6ba1(0x2ea)+_0x2f6ba1(0x1e1)+'ntion\x22,\x20\x22m'+_0x19b6b0(0x125)+_0x2f6ba1(0x1e9)+_0x2f6ba1(0x153)+_0x19b6b0(0x2bb)+_0x19b6b0(0x126)+_0x2f6ba1(0x30d)+_0x2f6ba1(0x29a)+_0x19b6b0(0x37d)+_0x19b6b0(0x3c4)+_0x19b6b0(0x38e)+_0x19b6b0(0x352)+_0x2f6ba1(0x250)+_0x19b6b0(0x16f)+_0x19b6b0(0x21a)+_0x2f6ba1(0x3c3)+'nabled\x22:\x20f'+_0x19b6b0(0x279)+'\x22socket_mo'+'de_enabled'+_0x2f6ba1(0x32f)+_0x19b6b0(0x34d)+_0x19b6b0(0x337)+_0x2f6ba1(0x36f)+'alse\x0a\x20\x20}\x0a}'),_0x2f6ba1(0x38f)+_0x19b6b0(0x267)+_0x19b6b0(0x3eb)+'e\x20App\x20with'+_0x19b6b0(0x223)+_0x19b6b0(0x16b)+_0x2f6ba1(0x3de)+_0x19b6b0(0x2b5),_0x19b6b0(0x103)+_0x2f6ba1(0x367)+_0x2f6ba1(0x269)+'tion\x20→\x20App'+_0x19b6b0(0x2fd)+_0x2f6ba1(0x242)+_0x2f6ba1(0x3ca)+'n\x20and\x20Scop'+_0x2f6ba1(0x2af)+_0x19b6b0(0x1f9)+'\x27,\x20pick\x20sc'+_0x19b6b0(0x142)+_0x2f6ba1(0x24c)+_0x19b6b0(0x147)+'\x20Generate.'+_0x19b6b0(0x3a5)+_0x19b6b0(0x1d9)+_0x19b6b0(0x31c)+_0x2f6ba1(0x171)+_0x19b6b0(0xed)+'w.',_0x19b6b0(0x103)+_0x2f6ba1(0xd5)+_0x19b6b0(0x358)+_0x19b6b0(0x393)+_0x2f6ba1(0x14a)+_0x19b6b0(0x1c7)+'\x20Copy\x20the\x20'+_0x19b6b0(0x3b9)+'OAuth\x20Toke'+'n\x27\x20(xoxb-.'+_0x2f6ba1(0x31d)+'LACK_BOT_T'+_0x19b6b0(0x321)+'.',_0x19b6b0(0x3d2)+'tokens\x20her'+_0x2f6ba1(0x273)+_0x19b6b0(0x2f7)+_0x19b6b0(0x241)+_0x2f6ba1(0x31f)+'nnection\x27\x20'+'—\x20you\x20shou'+_0x2f6ba1(0x344)+_0x19b6b0(0xdf)+_0x19b6b0(0xe0)+'.',_0x2f6ba1(0x3da)+_0x19b6b0(0x193)+'in\x20Mainten'+'ance\x20→\x20the'+'\x20Slack\x20ada'+'pter\x20conne'+_0x19b6b0(0x16d)+_0x2f6ba1(0x310)+_0x19b6b0(0x209)+'\x20Slack\x20con'+_0x2f6ba1(0x2f9)+_0x2f6ba1(0x1df)+'.',_0x2f6ba1(0x2b1)+_0x19b6b0(0x3af)+_0x19b6b0(0x150)+_0x2f6ba1(0xfb)+_0x2f6ba1(0x117)+_0x19b6b0(0x2c3)+'\x20send\x20a\x20DM'+_0x19b6b0(0x201)+_0x19b6b0(0x1c9)+_0x2f6ba1(0x2dc)+_0x19b6b0(0x306)+_0x2f6ba1(0x2ca)+_0x19b6b0(0x130)+_0x19b6b0(0x183)+_0x2f6ba1(0x1f3)+'n\x20help.',_0x19b6b0(0x114)+_0x19b6b0(0x3a6)+_0x2f6ba1(0x2c1)+'\x20bot\x20with\x20'+'/invite\x20@a'+_0x19b6b0(0x1ca)+_0x2f6ba1(0x34b)+_0x2f6ba1(0x3cf)+_0x19b6b0(0xc6)+_0x2f6ba1(0x395)+_0x19b6b0(0x357)+_0x19b6b0(0x1e6)+').']},{'id':'signal','name':_0x19b6b0(0x211),'icon':'🔒','description':'Signal\x20Mes'+_0x19b6b0(0x2de)+_0x19b6b0(0x26d)+_0x2f6ba1(0x233)+'.\x20Requires'+_0x2f6ba1(0x36a)+_0x2f6ba1(0x34c)+_0x19b6b0(0x205)+_0x2f6ba1(0x3d8),'envVars':[{'key':_0x19b6b0(0x1de)+_0x19b6b0(0x284),'label':'signal-cli'+'\x20REST\x20API\x20'+_0x19b6b0(0x266),'placeholder':_0x19b6b0(0x136)+_0x19b6b0(0x19c)+'0'},{'key':_0x2f6ba1(0x214)+_0x2f6ba1(0x332),'label':_0x2f6ba1(0x319)+_0x2f6ba1(0x1da),'placeholder':'+491234567'+_0x19b6b0(0x112)}],'setupUrl':_0x19b6b0(0x217)+_0x19b6b0(0x35c)+_0x19b6b0(0xd6)+'ignal-cli-'+_0x19b6b0(0x2da),'setupSteps':[_0x2f6ba1(0x18d)+_0x2f6ba1(0xd9)+_0x19b6b0(0x1f5)+'ker\x20recomm'+'ended):',_0x19b6b0(0x1c5)+_0x2f6ba1(0x3c5)+_0x19b6b0(0xf0)+_0x2f6ba1(0x1cf)+_0x2f6ba1(0x33a)+_0x2f6ba1(0x39c),_0x19b6b0(0x302)+'our\x20number'+_0x2f6ba1(0x1d5)+'PI',_0x2f6ba1(0x362)+_0x2f6ba1(0x178)+'\x20above']}],PROVIDERS=[{'id':_0x19b6b0(0x10f),'name':_0x2f6ba1(0x14b)+_0x19b6b0(0x359),'icon':'🟣','description':'Full\x20tool\x20'+_0x19b6b0(0x154)+'ent\x20SDK.\x20R'+_0x19b6b0(0xca)+_0x19b6b0(0x131)+_0x2f6ba1(0x1c6)+_0x2f6ba1(0x2f6)+'I\x20key).','envKey':'','models':[{'key':_0x19b6b0(0x10f),'name':_0x19b6b0(0x247)+_0x19b6b0(0x1cc),'model':_0x2f6ba1(0x316)+'s-4-6'}],'signupUrl':'https://co'+'nsole.anth'+_0x2f6ba1(0x3b2),'docsUrl':_0x2f6ba1(0x140)+'cs.anthrop'+_0x19b6b0(0xf2)+_0x19b6b0(0x10a)+'e-code','setupSteps':[_0x2f6ba1(0x19d)+_0x2f6ba1(0x2e1)+_0x2f6ba1(0x307)+_0x19b6b0(0x2a6),_0x19b6b0(0x168)+_0x19b6b0(0x376)+_0x2f6ba1(0x234)+_0x2f6ba1(0x22b),_0x19b6b0(0x372)+_0x2f6ba1(0x1bb)+_0x19b6b0(0x26b)+_0x19b6b0(0x1b0)+_0x2f6ba1(0x286)+'rowser']},{'id':_0x2f6ba1(0x185),'name':'Anthropic\x20'+_0x2f6ba1(0x293),'icon':'🟣','description':_0x19b6b0(0x3d9)+'s,\x20Sonnet,'+'\x20Haiku\x20dir'+_0x2f6ba1(0x122)+_0x19b6b0(0x28c)+_0x2f6ba1(0x385)+_0x19b6b0(0x198),'envKey':_0x19b6b0(0x259)+_0x19b6b0(0x206),'models':[{'key':_0x2f6ba1(0x316)+'s','name':'Claude\x20Opu'+_0x19b6b0(0x27e),'model':'claude-opu'+'s-4-6'},{'key':_0x19b6b0(0x113)+'net','name':_0x2f6ba1(0x2c4)+'net\x204.6','model':_0x19b6b0(0x113)+'net-4-6'},{'key':_0x19b6b0(0x391)+'ku','name':'Claude\x20Hai'+'ku\x204.5','model':_0x19b6b0(0x391)+_0x2f6ba1(0x265)}],'signupUrl':_0x19b6b0(0x225)+_0x2f6ba1(0x129)+_0x19b6b0(0x134)+'settings/k'+_0x19b6b0(0x2bd),'docsUrl':_0x19b6b0(0x140)+_0x19b6b0(0x16c)+_0x19b6b0(0xf2)+_0x2f6ba1(0x39c),'setupSteps':[_0x19b6b0(0x339)+'ount\x20on\x20co'+'nsole.anth'+_0x19b6b0(0x3b2),'Generate\x20A'+_0x19b6b0(0x276)+_0x19b6b0(0xff)+_0x19b6b0(0x11f)+'ys',_0x19b6b0(0x237)+'s\x20(pay-as-'+_0x19b6b0(0x270)+'\x20use\x20subsc'+'ription']},{'id':_0x2f6ba1(0x2aa),'name':_0x19b6b0(0x1b1),'icon':'🟢','description':_0x19b6b0(0x15e)+_0x19b6b0(0x3bd)+_0x19b6b0(0x180)+_0x2f6ba1(0x2d5)+_0x19b6b0(0x3b8),'envKey':_0x2f6ba1(0x3d0)+'_KEY','models':[{'key':_0x19b6b0(0x3e2),'name':_0x2f6ba1(0x2e4),'model':_0x2f6ba1(0x3e2)},{'key':_0x19b6b0(0x1d2)+'i','name':_0x2f6ba1(0x1e0)+'i','model':_0x2f6ba1(0x1d2)+'i'},{'key':_0x2f6ba1(0x305),'name':_0x2f6ba1(0x15b),'model':'gpt-4.1'},{'key':_0x2f6ba1(0x1dc)+'ni','name':_0x19b6b0(0x2c9)+'ni','model':_0x2f6ba1(0x1dc)+'ni'},{'key':'o3-mini','name':_0x2f6ba1(0x135),'model':_0x2f6ba1(0x10e)}],'signupUrl':_0x19b6b0(0x182)+_0x19b6b0(0x364)+_0x2f6ba1(0x1d7)+_0x2f6ba1(0x13b),'docsUrl':_0x19b6b0(0x182)+_0x2f6ba1(0x364)+_0x19b6b0(0x1f7)+'cs','setupSteps':[_0x2f6ba1(0x339)+'ount\x20on\x20pl'+_0x2f6ba1(0x364)+'nai.com',_0x19b6b0(0x218)+'PI\x20key\x20und'+'er\x20API\x20Key'+'s',_0x2f6ba1(0x237)+_0x2f6ba1(0x124)+'you-go)']},{'id':_0x19b6b0(0x172),'name':_0x19b6b0(0x382)+'ini','icon':'🔵','description':_0x19b6b0(0x324)+'/3\x20Pro/Fla'+_0x19b6b0(0x313)+_0x2f6ba1(0x2b9)+'dio.\x20Free\x20'+_0x2f6ba1(0x20e)+_0x19b6b0(0x143),'envKey':_0x19b6b0(0x28e)+_0x2f6ba1(0x102),'models':[{'key':_0x19b6b0(0x384)+'-pro','name':_0x19b6b0(0x324)+_0x2f6ba1(0x1f6),'model':_0x2f6ba1(0x384)+_0x2f6ba1(0x104)},{'key':_0x19b6b0(0x384)+_0x19b6b0(0x116),'name':_0x2f6ba1(0x324)+_0x2f6ba1(0x22d),'model':_0x19b6b0(0x384)+_0x2f6ba1(0x116)},{'key':'gemini-3-p'+'ro','name':_0x2f6ba1(0x3f5)+_0x2f6ba1(0x377)+'w)','model':_0x2f6ba1(0x239)+_0x19b6b0(0x2bc)},{'key':'gemini-3-f'+'lash','name':_0x2f6ba1(0x169)+_0x19b6b0(0x37e)+_0x2f6ba1(0xc5),'model':_0x2f6ba1(0x2a0)+_0x19b6b0(0x2ba)+'ew'}],'signupUrl':'https://ai'+_0x19b6b0(0x1f1)+_0x2f6ba1(0x25c)+_0x19b6b0(0x17f),'docsUrl':_0x19b6b0(0x1fc)+_0x2f6ba1(0x386)+'v/docs','setupSteps':[_0x19b6b0(0x163)+_0x19b6b0(0x213)+_0x19b6b0(0xe1)+_0x19b6b0(0x263)+'om)','Create\x20API'+'\x20key\x20→\x20rea'+_0x19b6b0(0x230)+'immediatel'+'y',_0x2f6ba1(0x2e5)+_0x19b6b0(0x1cd)+_0x19b6b0(0x318)],'free':!![]},{'id':_0x19b6b0(0x1d8),'name':_0x2f6ba1(0xc7),'icon':'🟩','description':'150+\x20model'+_0x19b6b0(0x2b6)+'ama,\x20Kimi,'+'\x20Mistral,\x20'+'etc.)\x20via\x20'+_0x19b6b0(0x312)+'.','envKey':_0x2f6ba1(0xd7)+_0x19b6b0(0x102),'models':[{'key':'nvidia-lla'+_0x19b6b0(0x184),'name':_0x19b6b0(0x373)+_0x2f6ba1(0x18a),'model':'meta/llama'+_0x19b6b0(0x22c)+'nstruct'},{'key':_0x2f6ba1(0xf7)+_0x19b6b0(0x2cb),'name':_0x2f6ba1(0x105),'model':_0x2f6ba1(0x33d)+'/kimi-k2.5'}],'signupUrl':_0x2f6ba1(0xf6)+_0x2f6ba1(0x216)+'.com','docsUrl':_0x2f6ba1(0x140)+_0x2f6ba1(0x3b1)+'dia.com','setupSteps':[_0x19b6b0(0x339)+'ount\x20on\x20bu'+_0x19b6b0(0x216)+'.com',_0x2f6ba1(0x191)+_0x19b6b0(0x381)+'y','150+\x20model'+_0x19b6b0(0x2ec)+_0x2f6ba1(0x35a)+_0x19b6b0(0x3ae)+'dits/month'+')'],'free':!![]},{'id':_0x2f6ba1(0x2dd),'name':'Groq','icon':'⚡','description':_0x2f6ba1(0x123)+_0x2f6ba1(0x27a)+_0x19b6b0(0x1b7)+_0x2f6ba1(0x325)+'mma\x20—\x20free'+_0x19b6b0(0x236)+'ning\x20fast.','envKey':_0x19b6b0(0x22f)+'EY','models':[{'key':'groq','name':_0x2f6ba1(0x373)+'70B\x20(Groq)','model':_0x19b6b0(0x2f1)+'70b-versat'+_0x19b6b0(0x29f)},{'key':'groq-llama'+_0x19b6b0(0x18e),'name':'Llama\x203.1\x20'+'8B\x20(Groq)','model':_0x19b6b0(0x30c)+_0x2f6ba1(0xd3)},{'key':_0x19b6b0(0x333)+'al','name':'Mixtral\x208x'+_0x2f6ba1(0x227),'model':_0x19b6b0(0x351)+'7b-32768'}],'signupUrl':_0x19b6b0(0x225)+_0x2f6ba1(0x2fe)+_0x2f6ba1(0x329),'docsUrl':_0x2f6ba1(0x225)+_0x2f6ba1(0x2fe)+_0x19b6b0(0x1d4),'setupSteps':['Create\x20acc'+'ount\x20on\x20co'+_0x2f6ba1(0x2fe)+_0x2f6ba1(0x282)+_0x2f6ba1(0xfa)+'\x20needed)','Generate\x20A'+_0x19b6b0(0x2b0),'Ready\x20to\x20u'+_0x19b6b0(0x111)+'tely\x20—\x20fre'+'e\x20tier\x20wit'+'h\x20rate\x20lim'+_0x2f6ba1(0x21c)],'free':!![]},{'id':_0x2f6ba1(0x3bf),'name':_0x2f6ba1(0x3f1),'icon':'🌐','description':_0x19b6b0(0x298)+'y,\x20200+\x20mo'+'dels.\x20Clau'+'de,\x20GPT,\x20G'+'emini,\x20Lla'+_0x2f6ba1(0xce)+_0x19b6b0(0x1e2)+'.','envKey':'OPENROUTER'+'_API_KEY','models':[{'key':_0x2f6ba1(0x3bf),'name':_0x19b6b0(0x3f1)+_0x2f6ba1(0x139)+')','model':_0x19b6b0(0x2f5)+_0x19b6b0(0x113)+_0x19b6b0(0x24b)}],'signupUrl':_0x19b6b0(0x23c)+'enrouter.a'+_0x19b6b0(0x2f3),'docsUrl':_0x2f6ba1(0x23c)+'enrouter.a'+_0x2f6ba1(0xf1),'setupSteps':[_0x19b6b0(0x339)+_0x2f6ba1(0xec)+_0x19b6b0(0x249)+'i',_0x2f6ba1(0x218)+_0x19b6b0(0x2b0),'Add\x20credit'+_0x19b6b0(0x2ef)+_0x2f6ba1(0x2f4)]},{'id':_0x19b6b0(0x21b),'name':_0x2f6ba1(0x2ce)+_0x19b6b0(0x152),'icon':'🦙','description':'Local\x20mode'+_0x19b6b0(0x3b3)+_0x19b6b0(0x14d)+_0x2f6ba1(0x264)+_0x19b6b0(0x1fb)+_0x19b6b0(0x24f)+'e.','envKey':'','models':[{'key':'ollama','name':_0x2f6ba1(0x2ce)+_0x19b6b0(0x152),'model':_0x19b6b0(0x2c7)}],'signupUrl':_0x2f6ba1(0x3cb)+'lama.com/d'+_0x2f6ba1(0x1f8),'docsUrl':_0x2f6ba1(0x3cb)+_0x19b6b0(0x387)+'ibrary','setupSteps':[_0x2f6ba1(0x23b)+'lama:\x20brew'+_0x2f6ba1(0x3e4)+_0x2f6ba1(0x301)+'OS)\x20or\x20oll'+_0x19b6b0(0x120)+_0x2f6ba1(0x20c),_0x2f6ba1(0x3ac)+_0x2f6ba1(0x155)+_0x19b6b0(0x138)+_0x2f6ba1(0x3e7),_0x2f6ba1(0x251)+_0x2f6ba1(0x3dd)+'n\x20localhos'+_0x2f6ba1(0x2a1)],'free':!![]}];export async function handleSetupAPI(_0x40b7ef,_0x5765fc,_0x4c0e13,_0x4c18f2){const _0x3fa191=_0x2f6ba1,_0x36d6b4=_0x19b6b0;_0x5765fc[_0x3fa191(0x335)]('Content-Ty'+'pe','applicatio'+'n/json');if(_0x4c0e13===_0x36d6b4(0x253)+'orms/setup'){const _0x3e70d1=readEnv(),_0x1235c1=PLATFORMS[_0x36d6b4(0x14e)](_0x4c5aa0=>({..._0x4c5aa0,'configured':((()=>{const _0x2b0459=_0x3fa191,_0x12568d=_0x3fa191,_0x506121=_0x4c5aa0[_0x2b0459(0x36e)][_0x2b0459(0x235)](_0x568aaf=>_0x568aaf[_0x12568d(0x3d7)]!==_0x2b0459(0x2cc)),_0x4e40fb=_0x4c5aa0[_0x12568d(0x36e)][_0x2b0459(0x235)](_0x57b24f=>_0x57b24f[_0x2b0459(0x3d7)]===_0x12568d(0x2cc));if(_0x506121[_0x2b0459(0xee)]>0x1*-0x31d+-0x2239+0x2556)return _0x506121[_0x2b0459(0x1bc)](_0x1bc107=>!!_0x3e70d1[_0x1bc107[_0x12568d(0x3a4)]]);if(_0x4e40fb[_0x2b0459(0xee)]>0x6*0x69+-0x2180+0x1f0a)return _0x4e40fb[0x33a*0x9+0x1557+-0x10cb*0x3]&&_0x3e70d1[_0x4e40fb[-0x5d+-0x428*-0x5+0x1*-0x146b][_0x12568d(0x3a4)]]===_0x2b0459(0x2b2);return![];})()),'values':Object[_0x3fa191(0x29b)+'s'](_0x4c5aa0['envVars'][_0x36d6b4(0x14e)](_0x4556b1=>[_0x4556b1[_0x3fa191(0x3a4)],_0x4556b1[_0x3fa191(0x2eb)]&&_0x3e70d1[_0x4556b1[_0x36d6b4(0x3a4)]]?maskSecret(_0x3e70d1[_0x4556b1[_0x3fa191(0x3a4)]]):_0x3e70d1[_0x4556b1[_0x3fa191(0x3a4)]]||''])),'depsInstalled':_0x4c5aa0['npmPackage'+'s']?checkNpmDeps(_0x4c5aa0[_0x3fa191(0x1a7)+'s']):!![]}));return _0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'platforms':_0x1235c1})),!![];}if(_0x4c0e13==='/api/platf'+_0x3fa191(0x37b)+_0x3fa191(0x35d)&&_0x40b7ef['method']===_0x3fa191(0x1b6)){try{const {platformId:_0xcfadab,values:_0x3de1b5}=JSON[_0x3fa191(0x31a)](_0x4c18f2),_0x1bf65a=PLATFORMS[_0x3fa191(0x141)](_0x23ffb9=>_0x23ffb9['id']===_0xcfadab);if(!_0x1bf65a)return _0x5765fc[_0x36d6b4(0x20b)]=0x2*0x12e7+0x10ed+0x352b*-0x1,_0x5765fc[_0x3fa191(0x2c8)](JSON['stringify']({'error':_0x36d6b4(0x38b)+_0x3fa191(0x3a7)})),!![];for(const _0x1c2575 of _0x1bf65a[_0x36d6b4(0x36e)]){if(_0x3de1b5[_0x1c2575[_0x36d6b4(0x3a4)]]!==undefined&&_0x3de1b5[_0x1c2575[_0x3fa191(0x3a4)]]!=='')writeEnvVar(_0x1c2575[_0x3fa191(0x3a4)],_0x3de1b5[_0x1c2575['key']]),process['env'][_0x1c2575[_0x36d6b4(0x3a4)]]=_0x3de1b5[_0x1c2575[_0x36d6b4(0x3a4)]];else _0x3de1b5[_0x1c2575[_0x36d6b4(0x3a4)]]===''&&(removeEnvVar(_0x1c2575[_0x36d6b4(0x3a4)]),delete process[_0x3fa191(0x3b0)][_0x1c2575[_0x3fa191(0x3a4)]]);}const _0x532ddc=_0x1bf65a[_0x3fa191(0x36e)][_0x3fa191(0x1bc)](_0x73d42d=>_0x73d42d[_0x36d6b4(0x3d7)]===_0x3fa191(0x2cc))||_0xcfadab===_0x36d6b4(0x149)&&_0x1bf65a[_0x36d6b4(0x36e)][_0x3fa191(0x235)](_0x1b5090=>_0x1b5090[_0x36d6b4(0x3d7)]!==_0x3fa191(0x2cc))[_0x3fa191(0x1bc)](_0x19db15=>!_0x3de1b5[_0x19db15[_0x36d6b4(0x3a4)]]),_0x34ae1e=!_0x532ddc;_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':!![],'restartNeeded':_0x34ae1e,'note':_0x34ae1e?_0x36d6b4(0x21d)+_0x3fa191(0x299)+_0x3fa191(0x175)+'ges.':_0x36d6b4(0x115)}));}catch{_0x5765fc['statusCode']=-0x432+0xf1*-0x13+0x17a5,_0x5765fc['end'](JSON[_0x36d6b4(0x208)]({'error':_0x3fa191(0x2c0)+_0x36d6b4(0x2bf)}));}return!![];}if(_0x4c0e13===_0x36d6b4(0x253)+_0x3fa191(0x161)+_0x36d6b4(0x3f4)&&_0x40b7ef[_0x3fa191(0x3bb)]===_0x36d6b4(0x1b6)){try{const {platformId:_0x18c227}=JSON[_0x3fa191(0x31a)](_0x4c18f2),_0x555425=PLATFORMS[_0x3fa191(0x141)](_0x26733d=>_0x26733d['id']===_0x18c227);if(!_0x555425?.['npmPackage'+'s']?.[_0x36d6b4(0xee)])return _0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':!![],'note':_0x36d6b4(0x1ac)+'ncies\x20need'+'ed.'})),!![];const _0x34cb27=_0x555425[_0x36d6b4(0x1a7)+'s'][_0x3fa191(0x33b)]('\x20'),_0xe1810b=execSync(_0x3fa191(0x309)+BOT_ROOT+(_0x3fa191(0x3b6)+_0x3fa191(0x2fc))+_0x34cb27+('\x20--save-op'+_0x36d6b4(0x1c2)+'1'),{'timeout':0x1d4c0,'env':{...process[_0x36d6b4(0x3b0)],'PATH':process[_0x36d6b4(0x3b0)][_0x36d6b4(0x36b)]+(_0x36d6b4(0x370)+'brew/bin:/'+_0x36d6b4(0xea)+'bin')}})[_0x3fa191(0x37c)]();_0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':!![],'output':_0xe1810b[_0x3fa191(0x3be)](0x1*-0x1ec1+0x86*-0x4+-0x1*-0x20d9,0x5a2+-0x214d+0x2f33)}));}catch(_0x2c98c5){const _0x1477b9=_0x2c98c5 instanceof Error?_0x2c98c5[_0x3fa191(0xe2)]:String(_0x2c98c5);_0x5765fc[_0x3fa191(0x2c8)](JSON['stringify']({'error':_0x1477b9}));}return!![];}if(_0x4c0e13===_0x3fa191(0x27f)+'ders/setup'){const _0x418fe2=readEnv(),_0x37197b=getRegistry(),_0x3caa21=_0x37197b[_0x3fa191(0xdc)+'ey'](),_0x54cdd0=await _0x37197b[_0x36d6b4(0x2ad)](),_0x3b3a26=PROVIDERS[_0x3fa191(0x14e)](_0x398ef4=>({..._0x398ef4,'hasKey':_0x398ef4[_0x36d6b4(0xdd)]?!!_0x418fe2[_0x398ef4[_0x3fa191(0xdd)]]:!![],'keyPreview':_0x398ef4[_0x3fa191(0xdd)]&&_0x418fe2[_0x398ef4['envKey']]?maskSecret(_0x418fe2[_0x398ef4[_0x36d6b4(0xdd)]]):'','modelsActive':_0x398ef4[_0x3fa191(0x13e)][_0x36d6b4(0x14e)](_0x7368a2=>({..._0x7368a2,'registered':_0x54cdd0[_0x36d6b4(0x360)](_0x351bcd=>_0x351bcd[_0x3fa191(0x3a4)]===_0x7368a2[_0x3fa191(0x3a4)]),'active':_0x3caa21===_0x7368a2[_0x3fa191(0x3a4)],'status':_0x54cdd0[_0x3fa191(0x141)](_0xfe0b18=>_0xfe0b18[_0x3fa191(0x3a4)]===_0x7368a2['key'])?.[_0x36d6b4(0x11a)]||'not\x20config'+_0x36d6b4(0xf3)}))})),_0x303e8c=loadCustomModels();return _0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'providers':_0x3b3a26,'customModels':_0x303e8c,'activeModel':_0x3caa21})),!![];}if(_0x4c0e13===_0x36d6b4(0x27f)+_0x3fa191(0x14f)+'ey'&&_0x40b7ef[_0x3fa191(0x3bb)]===_0x3fa191(0x1b6)){try{const {providerId:_0x5f28c4,apiKey:_0x16e23f}=JSON[_0x3fa191(0x31a)](_0x4c18f2),_0x93d32f=PROVIDERS[_0x3fa191(0x141)](_0x569dca=>_0x569dca['id']===_0x5f28c4);if(!_0x93d32f?.['envKey'])return _0x5765fc[_0x36d6b4(0x20b)]=-0x2199+0x2*0x2fe+-0x61*-0x4d,_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x36d6b4(0x208)]({'error':_0x3fa191(0x394)+_0x3fa191(0x343)+_0x3fa191(0x1e7)+_0x3fa191(0x3a4)})),!![];writeEnvVar(_0x93d32f[_0x3fa191(0xdd)],_0x16e23f),_0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'ok':!![],'note':_0x3fa191(0x21d)+'quired\x20to\x20'+_0x36d6b4(0x3ad)+_0x36d6b4(0x2be)+'.'}));}catch{_0x5765fc['statusCode']=0xc*-0x149+0xa8*0x13+-0x242*-0x2,_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'error':_0x3fa191(0x2c0)+_0x36d6b4(0x2bf)}));}return!![];}if(_0x4c0e13==='/api/provi'+'ders/set-p'+_0x36d6b4(0x13f)&&_0x40b7ef['method']===_0x3fa191(0x1b6)){try{const {key:_0x2a9174}=JSON[_0x36d6b4(0x31a)](_0x4c18f2);writeEnvVar(_0x36d6b4(0x156)+_0x3fa191(0x2d1),_0x2a9174);const _0x107c6f=getRegistry();_0x107c6f[_0x36d6b4(0x3ce)](_0x2a9174),_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':!![]}));}catch{_0x5765fc['statusCode']=-0xba*-0x3+0x1*0x1f7+-0x295,_0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'error':'Invalid\x20re'+_0x36d6b4(0x2bf)}));}return!![];}if(_0x4c0e13===_0x3fa191(0x27f)+'ders/set-f'+_0x3fa191(0x2d3)&&_0x40b7ef[_0x36d6b4(0x3bb)]==='POST'){try{const {keys:_0x2df7a1}=JSON[_0x3fa191(0x31a)](_0x4c18f2);writeEnvVar(_0x3fa191(0x3a2)+_0x36d6b4(0x34a),_0x2df7a1['join'](',')),_0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':!![],'note':'Restart\x20re'+_0x36d6b4(0x31b)}));}catch{_0x5765fc[_0x36d6b4(0x20b)]=0x21a4+-0xcc7*0x1+-0x3d*0x51,_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'error':_0x3fa191(0x2c0)+'quest'}));}return!![];}if(_0x4c0e13?.[_0x3fa191(0x3b5)](_0x3fa191(0x27f)+'ders/live-'+_0x36d6b4(0x13e))&&_0x40b7ef[_0x3fa191(0x3bb)]==='GET'){try{const _0x40576e=new URL(_0x40b7ef['url']||'',_0x36d6b4(0x1ae)+_0x40b7ef[_0x36d6b4(0x121)][_0x3fa191(0x2ed)]),_0x57267e=_0x40576e[_0x36d6b4(0x2ab)+'ms'][_0x3fa191(0x30a)]('id')||'',_0xc7d1fa=await fetchLiveModels(_0x57267e);_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':!![],'providerId':_0x57267e,'models':_0xc7d1fa}));}catch(_0x3abf44){_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':![],'error':_0x3abf44 instanceof Error?_0x3abf44[_0x3fa191(0xe2)]:String(_0x3abf44),'models':[]}));}return!![];}if(_0x4c0e13===_0x3fa191(0x27f)+'ders/add-c'+_0x3fa191(0x2df)&&_0x40b7ef[_0x3fa191(0x3bb)]==='POST'){try{const _0x2fab5f=JSON[_0x36d6b4(0x31a)](_0x4c18f2);if(!_0x2fab5f['key']||!_0x2fab5f[_0x3fa191(0x162)]||!_0x2fab5f[_0x36d6b4(0x13a)]||!_0x2fab5f[_0x36d6b4(0x17d)])return _0x5765fc[_0x3fa191(0x20b)]=0x208f+0x2*-0xa1c+-0xac7,_0x5765fc[_0x3fa191(0x2c8)](JSON['stringify']({'error':_0x3fa191(0x13c)+'\x20baseUrl\x20a'+_0x3fa191(0x101)+_0x36d6b4(0x1c1)+'d\x20fields'})),!![];_0x2fab5f['type']=_0x36d6b4(0x10d)+_0x3fa191(0x1c0);const _0x17225f=loadCustomModels(),_0x39a248=_0x17225f[_0x3fa191(0x36c)](_0x2d7bbb=>_0x2d7bbb[_0x36d6b4(0x3a4)]===_0x2fab5f[_0x3fa191(0x3a4)]);if(_0x39a248>=0x141b+0x17df+0xd*-0x362)_0x17225f[_0x39a248]=_0x2fab5f;else _0x17225f[_0x36d6b4(0x1d0)](_0x2fab5f);saveCustomModels(_0x17225f),_0x2fab5f[_0x3fa191(0x389)]&&_0x2fab5f[_0x36d6b4(0x289)]&&writeEnvVar(_0x2fab5f[_0x3fa191(0x389)],_0x2fab5f['apiKey']),_0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':!![],'note':_0x36d6b4(0x21d)+_0x36d6b4(0x299)+_0x36d6b4(0x3ad)+'he\x20model.'}));}catch{_0x5765fc[_0x36d6b4(0x20b)]=0x146*-0x1+-0x2599+-0x3ad*-0xb,_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'error':_0x3fa191(0x2c0)+'quest'}));}return!![];}if(_0x4c0e13===_0x36d6b4(0x27f)+_0x3fa191(0x1a6)+_0x36d6b4(0x1cb)&&_0x40b7ef[_0x3fa191(0x3bb)]===_0x36d6b4(0x1b6)){try{const {key:_0x4d0704}=JSON[_0x36d6b4(0x31a)](_0x4c18f2),_0x151bfd=loadCustomModels()[_0x36d6b4(0x235)](_0x598537=>_0x598537[_0x3fa191(0x3a4)]!==_0x4d0704);saveCustomModels(_0x151bfd),_0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':!![]}));}catch{_0x5765fc[_0x36d6b4(0x20b)]=-0xfaf+-0x59*-0x3a+0x3*-0xf9,_0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'error':_0x3fa191(0x2c0)+'quest'}));}return!![];}if(_0x4c0e13===_0x36d6b4(0x27f)+'ders/test-'+_0x3fa191(0x3a4)&&_0x40b7ef['method']==='POST'){try{const {providerId:_0x358b05,apiKey:_0x1e8ebe}=JSON[_0x36d6b4(0x31a)](_0x4c18f2),_0x439464=await testApiKey(_0x358b05,_0x1e8ebe);_0x5765fc['end'](JSON[_0x36d6b4(0x208)](_0x439464));}catch(_0x8abb15){const _0x68076d=_0x8abb15 instanceof Error?_0x8abb15['message']:String(_0x8abb15);_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':![],'error':_0x68076d}));}return!![];}if(_0x4c0e13===_0x3fa191(0x257)+_0x3fa191(0x11a)){const _0x57d4a5=await getSudoStatus();return _0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)](_0x57d4a5)),!![];}if(_0x4c0e13===_0x36d6b4(0x257)+_0x36d6b4(0x272)&&_0x40b7ef[_0x36d6b4(0x3bb)]===_0x3fa191(0x1b6)){try{const {password:_0x486484}=JSON['parse'](_0x4c18f2);if(!_0x486484)return _0x5765fc[_0x3fa191(0x20b)]=0x1d74+0x20b5*0x1+0x1*-0x3c99,_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'error':_0x3fa191(0x11b)+_0x3fa191(0x32d)})),!![];const _0xc0135=storePassword(_0x486484);if(_0xc0135['ok']){const _0x584908=await verifyPassword();_0x584908['ok']?_0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'ok':!![],'method':_0xc0135[_0x3fa191(0x3bb)],'verified':!![]})):(revokePassword(),_0x5765fc[_0x3fa191(0x2c8)](JSON['stringify']({'ok':![],'error':_0x3fa191(0x2f2)+'tored\x20but\x20'+_0x3fa191(0x378)+_0x36d6b4(0x274)+'\x20'+_0x584908[_0x36d6b4(0x392)]})));}else _0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':![],'error':_0xc0135['error']}));}catch{_0x5765fc[_0x3fa191(0x20b)]=-0x2059+-0x10*-0x23a+-0x1b7,_0x5765fc['end'](JSON[_0x3fa191(0x208)]({'error':'Invalid\x20re'+'quest'}));}return!![];}if(_0x4c0e13===_0x3fa191(0x257)+_0x3fa191(0x24a)&&_0x40b7ef['method']===_0x3fa191(0x1b6)){const _0x2abcfd=revokePassword();return _0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':_0x2abcfd})),!![];}if(_0x4c0e13==='/api/sudo/'+_0x3fa191(0xe6)&&_0x40b7ef[_0x36d6b4(0x3bb)]===_0x3fa191(0x1b6)){const _0x33b1dc=await verifyPassword();return _0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)](_0x33b1dc)),!![];}if(_0x4c0e13===_0x36d6b4(0x257)+_0x3fa191(0x144)&&_0x40b7ef[_0x36d6b4(0x3bb)]===_0x36d6b4(0x1b6)){try{const {command:_0x230275}=JSON[_0x3fa191(0x31a)](_0x4c18f2);if(!_0x230275)return _0x5765fc[_0x36d6b4(0x20b)]=-0x1*-0x1abf+-0x2e5*0x5+0x1*-0xab6,_0x5765fc[_0x3fa191(0x2c8)](JSON['stringify']({'error':_0x3fa191(0x158)+_0x36d6b4(0x12f)})),!![];const _0x19f1bd=await sudoExec(_0x230275);_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)](_0x19f1bd));}catch{_0x5765fc[_0x36d6b4(0x20b)]=0x2e7+-0x1*-0x21bd+-0x2314,_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x36d6b4(0x208)]({'error':_0x36d6b4(0x2c0)+_0x36d6b4(0x2bf)}));}return!![];}if(_0x4c0e13===_0x36d6b4(0x257)+_0x36d6b4(0x3e0)+'og'&&_0x40b7ef[_0x36d6b4(0x3bb)]==='POST'){try{const {reason:_0xc9d850}=JSON[_0x36d6b4(0x31a)](_0x4c18f2),_0x373102=await requestAdminViaDialog(_0xc9d850||_0x3fa191(0x26e)+_0x36d6b4(0x226)+'dministrat'+_0x36d6b4(0x25d)+_0x3fa191(0x38d));_0x5765fc['end'](JSON[_0x3fa191(0x208)](_0x373102));}catch{_0x5765fc[_0x36d6b4(0x20b)]=-0x1*0x577+0x159c+-0xe95,_0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'error':'Invalid\x20re'+_0x36d6b4(0x2bf)}));}return!![];}if(_0x4c0e13===_0x3fa191(0x257)+_0x3fa191(0x194)+_0x36d6b4(0x157)&&_0x40b7ef[_0x3fa191(0x3bb)]===_0x36d6b4(0x1b6)){try{const {pane:_0x507b70}=JSON[_0x36d6b4(0x31a)](_0x4c18f2),_0x5f3188=openSystemSettings(_0x507b70||_0x3fa191(0x18f));_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':_0x5f3188}));}catch{_0x5765fc[_0x3fa191(0x20b)]=-0xe*-0x137+-0x2*-0x75a+-0x1e26,_0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'error':_0x36d6b4(0x2c0)+_0x36d6b4(0x2bf)}));}return!![];}if(_0x4c0e13===_0x36d6b4(0x12c)+'s'){const {getSkills:_0x245498}=await import(_0x3fa191(0x280)+_0x36d6b4(0x1d3)+'s'),_0x2572ef=_0x245498()[_0x36d6b4(0x14e)](_0x3c7253=>({'id':_0x3c7253['id'],'name':_0x3c7253[_0x3fa191(0x162)],'description':_0x3c7253[_0x3fa191(0xf4)+'n'],'triggers':_0x3c7253[_0x36d6b4(0x16e)],'priority':_0x3c7253[_0x36d6b4(0x18c)],'category':_0x3c7253[_0x36d6b4(0x224)]}));return _0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'skills':_0x2572ef})),!![];}if(_0x4c0e13===_0x3fa191(0x1fe)){const _0x50c8ff=listJobs(),_0x375e30=_0x50c8ff[_0x36d6b4(0x14e)](_0x49040a=>({..._0x49040a,'nextRunFormatted':formatNextRun(_0x49040a[_0x36d6b4(0x3ef)]),'lastRunFormatted':_0x49040a[_0x3fa191(0x281)]?new Date(_0x49040a[_0x36d6b4(0x281)])[_0x36d6b4(0x1ba)+_0x36d6b4(0x106)](_0x36d6b4(0x32a)):null,'scheduleReadable':humanReadableSchedule(_0x49040a[_0x36d6b4(0x1c3)])}));return _0x5765fc['end'](JSON[_0x36d6b4(0x208)]({'jobs':_0x375e30})),!![];}if(_0x4c0e13===_0x36d6b4(0x3c8)+_0x36d6b4(0x203)&&_0x40b7ef[_0x36d6b4(0x3bb)]==='POST'){try{const _0x232e43=JSON[_0x36d6b4(0x31a)](_0x4c18f2),_0x1bc917=createJob({'name':_0x232e43[_0x36d6b4(0x162)],'type':_0x232e43[_0x3fa191(0x3d7)],'schedule':_0x232e43[_0x3fa191(0x1c3)],'oneShot':_0x232e43[_0x36d6b4(0x3ab)]||![],'payload':_0x232e43['payload']||{},'target':_0x232e43[_0x36d6b4(0x221)]||{'platform':_0x36d6b4(0x29e),'chatId':_0x3fa191(0x12e)},'createdBy':_0x36d6b4(0x35e)});_0x5765fc['end'](JSON['stringify']({'ok':!![],'job':_0x1bc917}));}catch(_0x782d61){_0x5765fc['statusCode']=0x26a7*0x1+0x1365+0x6*-0x96a;const _0x5b70be=_0x782d61 instanceof Error?_0x782d61[_0x3fa191(0xe2)]:'Invalid\x20re'+_0x3fa191(0x2bf);_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'error':_0x5b70be}));}return!![];}if(_0x4c0e13===_0x3fa191(0x3c8)+_0x3fa191(0x2cf)&&_0x40b7ef[_0x3fa191(0x3bb)]===_0x3fa191(0x1b6)){try{const {id:_0x25e43b}=JSON[_0x36d6b4(0x31a)](_0x4c18f2),_0x10e55e=deleteJob(_0x25e43b);_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':_0x10e55e}));}catch{_0x5765fc[_0x36d6b4(0x20b)]=0x1991+-0x36a+-0xfb*0x15,_0x5765fc['end'](JSON[_0x36d6b4(0x208)]({'error':_0x36d6b4(0x2c0)+'quest'}));}return!![];}if(_0x4c0e13===_0x36d6b4(0x3c8)+_0x36d6b4(0x1a3)&&_0x40b7ef[_0x3fa191(0x3bb)]===_0x36d6b4(0x1b6)){try{const {id:_0x5006bc,..._0x250e97}=JSON[_0x36d6b4(0x31a)](_0x4c18f2);if(!_0x5006bc)return _0x5765fc[_0x36d6b4(0x20b)]=-0x50d*-0x5+-0x6e3+-0x6*0x2cd,_0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'error':'id\x20require'+'d'})),!![];const _0x492ef6={};if(_0x250e97['schedule']!==undefined)_0x492ef6['schedule']=_0x250e97[_0x3fa191(0x1c3)];if(_0x250e97['name']!==undefined)_0x492ef6[_0x36d6b4(0x162)]=_0x250e97[_0x3fa191(0x162)];if(_0x250e97[_0x3fa191(0x3ab)]!==undefined)_0x492ef6[_0x3fa191(0x3ab)]=_0x250e97[_0x3fa191(0x3ab)];const _0x1ddeb6=updateJob(_0x5006bc,_0x492ef6);if(!_0x1ddeb6)return _0x5765fc[_0x3fa191(0x20b)]=-0x6f7*0x4+-0x4*-0x1bf+0x1674,_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)]({'error':_0x36d6b4(0x29d)+_0x3fa191(0x1b5)})),!![];_0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':!![],'job':_0x1ddeb6}));}catch(_0x1445ab){_0x5765fc[_0x36d6b4(0x20b)]=0xd3c+0x19*-0xa5+0x471;const _0x3bf680=_0x1445ab instanceof Error?_0x1445ab[_0x3fa191(0xe2)]:'Invalid\x20re'+_0x3fa191(0x2bf);_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)]({'error':_0x3bf680}));}return!![];}if(_0x4c0e13===_0x36d6b4(0x3c8)+'toggle'&&_0x40b7ef['method']===_0x3fa191(0x1b6)){try{const {id:_0x52f218}=JSON[_0x3fa191(0x31a)](_0x4c18f2),_0x2c7630=toggleJob(_0x52f218);_0x5765fc['end'](JSON['stringify']({'ok':!!_0x2c7630,'job':_0x2c7630}));}catch{_0x5765fc[_0x36d6b4(0x20b)]=0xb3f*0x1+0x7*0x33b+-0x204c,_0x5765fc[_0x36d6b4(0x2c8)](JSON['stringify']({'error':'Invalid\x20re'+_0x36d6b4(0x2bf)}));}return!![];}if(_0x4c0e13===_0x3fa191(0x3c8)+_0x3fa191(0x20d)&&_0x40b7ef[_0x3fa191(0x3bb)]===_0x36d6b4(0x1b6)){try{const {id:_0x52f139}=JSON['parse'](_0x4c18f2),_0x4e9eb6=await(runJobNow(_0x52f139)||Promise[_0x3fa191(0x320)]({'output':'','error':'Job\x20not\x20fo'+'und'}));_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)](_0x4e9eb6));}catch(_0x4c538e){const _0x5e680b=_0x4c538e instanceof Error?_0x4c538e[_0x36d6b4(0xe2)]:String(_0x4c538e);_0x5765fc['end'](JSON[_0x36d6b4(0x208)]({'error':_0x5e680b}));}return!![];}if(_0x4c0e13===_0x3fa191(0x253)+_0x3fa191(0x39a)+'s'){const _0x5dbc50={};try{const {getTelegramState:_0x48c2db}=await import(_0x36d6b4(0x261)+'ms/telegra'+_0x3fa191(0x14c));_0x5dbc50[_0x36d6b4(0x390)]=_0x48c2db();}catch{_0x5dbc50['telegram']={'status':!!process['env'][_0x36d6b4(0x28b)]?_0x3fa191(0x3e1):_0x3fa191(0x10b)+_0x3fa191(0xf3)};}try{const {getDiscordState:_0x387816}=await import(_0x3fa191(0x261)+_0x36d6b4(0x23f)+'.js');_0x5dbc50[_0x3fa191(0x341)]=_0x387816();}catch{_0x5dbc50[_0x3fa191(0x341)]={'status':!!process[_0x36d6b4(0x3b0)][_0x3fa191(0x334)+_0x3fa191(0x1bf)]?_0x36d6b4(0x3e1):_0x3fa191(0x10b)+'ured'};}try{const {getWhatsAppState:_0x1b3b5a}=await import('../platfor'+_0x36d6b4(0x1a0)+'p.js');_0x5dbc50[_0x36d6b4(0x149)]=_0x1b3b5a();}catch{_0x5dbc50[_0x3fa191(0x149)]={'status':process[_0x3fa191(0x3b0)][_0x36d6b4(0x1ef)+_0x36d6b4(0x294)]===_0x3fa191(0x2b2)?_0x36d6b4(0x3e1):_0x3fa191(0x10b)+'ured'};}try{const {getSignalState:_0x55cbca}=await import(_0x3fa191(0x261)+_0x36d6b4(0x3e8)+'js');_0x5dbc50[_0x36d6b4(0x262)]=_0x55cbca();}catch{_0x5dbc50[_0x36d6b4(0x262)]={'status':!!process[_0x36d6b4(0x3b0)][_0x36d6b4(0x1de)+_0x3fa191(0x284)]?_0x3fa191(0x3e1):_0x36d6b4(0x10b)+_0x3fa191(0xf3)};}return _0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)](_0x5dbc50)),!![];}if(_0x4c0e13==='/api/whats'+_0x3fa191(0x159)){try{const {getWhatsAppState:_0x2a8dcf}=await import(_0x36d6b4(0x261)+_0x36d6b4(0x1a0)+'p.js'),_0x4d1cc2=_0x2a8dcf();_0x5765fc[_0x3fa191(0x2c8)](JSON['stringify'](_0x4d1cc2));}catch{_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)]({'status':_0x36d6b4(0x23a)+'ed','qrString':null,'error':_0x36d6b4(0x3e9)+'dapter\x20not'+_0x3fa191(0xfc)}));}return!![];}if(_0x4c0e13==='/api/whats'+_0x36d6b4(0x3c1)+_0x36d6b4(0x3ed)&&_0x40b7ef[_0x36d6b4(0x3bb)]==='POST'){try{const _0x2df324=WHATSAPP_AUTH;_0x5450d7[_0x36d6b4(0xcc)](_0x2df324)&&_0x5450d7[_0x3fa191(0x27c)](_0x2df324,{'recursive':!![]}),_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':!![],'note':'Auth\x20data\x20'+_0x36d6b4(0x2e0)+_0x3fa191(0x3b4)+_0x36d6b4(0x3cc)+_0x3fa191(0x1f0)+_0x36d6b4(0x170)}));}catch(_0x234f87){const _0x23412e=_0x234f87 instanceof Error?_0x234f87[_0x3fa191(0xe2)]:String(_0x234f87);_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':![],'error':_0x23412e}));}return!![];}if(_0x4c0e13===_0x36d6b4(0x253)+_0x3fa191(0x26a)+_0x3fa191(0x219)&&_0x40b7ef['method']==='POST'){try{const {platformId:_0x58a922}=JSON['parse'](_0x4c18f2);if(_0x58a922==='telegram'){const _0x50534c=process[_0x36d6b4(0x3b0)]['BOT_TOKEN'];if(!_0x50534c)return _0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':![],'error':_0x36d6b4(0x38a)+_0x3fa191(0x315)})),!![];const _0x434882=await fetch(_0x3fa191(0x2ff)+_0x3fa191(0x254)+_0x3fa191(0x365)+_0x50534c+'/getMe'),_0x27a87b=await _0x434882[_0x3fa191(0x2c5)]();return _0x27a87b['ok']?_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':!![],'info':'@'+_0x27a87b[_0x36d6b4(0x380)][_0x3fa191(0x186)]+'\x20('+_0x27a87b[_0x36d6b4(0x380)][_0x36d6b4(0xcf)]+')'})):_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':![],'error':_0x27a87b['descriptio'+'n']||_0x3fa191(0x118)+_0x36d6b4(0x21e)})),!![];}if(_0x58a922===_0x3fa191(0x341)){const _0x827ad2=process[_0x36d6b4(0x3b0)][_0x36d6b4(0x334)+_0x3fa191(0x1bf)];if(!_0x827ad2)return _0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':![],'error':'DISCORD_TO'+_0x3fa191(0x353)+'t'})),!![];const _0x2ea299=await fetch(_0x36d6b4(0x187)+'scord.com/'+_0x3fa191(0x33e)+'ers/@me',{'headers':{'Authorization':_0x36d6b4(0x204)+_0x827ad2}}),_0x4be614=await _0x2ea299['json']();return _0x4be614['id']?_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':!![],'info':_0x4be614[_0x3fa191(0x186)]+'#'+(_0x4be614[_0x3fa191(0x277)+_0x3fa191(0x271)]||'0')+_0x3fa191(0x356)+_0x4be614['id']+')'})):_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':![],'error':_0x4be614[_0x36d6b4(0xe2)]||_0x3fa191(0x118)+_0x36d6b4(0x21e)})),!![];}if(_0x58a922===_0x3fa191(0x262)){const _0x175b17=process[_0x36d6b4(0x3b0)]['SIGNAL_API'+_0x3fa191(0x284)];if(!_0x175b17)return _0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':![],'error':_0x36d6b4(0x1de)+_0x36d6b4(0x1be)+'et'})),!![];const _0x5e4d5a=await fetch(_0x175b17['replace'](/\/$/,'')+_0x3fa191(0xfd));if(_0x5e4d5a['ok']){const _0x3f43fb=await _0x5e4d5a[_0x36d6b4(0x2c5)]();_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':!![],'info':_0x3fa191(0x128)+_0x36d6b4(0x199)+(_0x3f43fb['version']||'?')+_0x36d6b4(0x19e)}));}else _0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':![],'error':_0x36d6b4(0x23e)+_0x3fa191(0xc8)+_0x5e4d5a['status']}));return!![];}if(_0x58a922===_0x3fa191(0x149)){try{const {getWhatsAppState:_0x2e5010}=await import(_0x3fa191(0x261)+_0x3fa191(0x1a0)+_0x3fa191(0xd4)),_0x4a72e8=_0x2e5010();_0x5765fc[_0x3fa191(0x2c8)](JSON['stringify']({'ok':_0x4a72e8[_0x36d6b4(0x11a)]===_0x3fa191(0xf9),'info':'Status:\x20'+_0x4a72e8[_0x3fa191(0x11a)]}));}catch{_0x5765fc['end'](JSON['stringify']({'ok':![],'error':'WhatsApp\x20a'+_0x36d6b4(0x3d3)+_0x36d6b4(0xfc)}));}return!![];}if(_0x58a922==='slack'){const _0x538d40=process[_0x36d6b4(0x3b0)]['SLACK_BOT_'+_0x36d6b4(0xe3)],_0x2db35f=process['env'][_0x3fa191(0x171)+_0x3fa191(0xe3)];if(!_0x538d40)return _0x5765fc[_0x3fa191(0x2c8)](JSON[_0x3fa191(0x208)]({'ok':![],'error':_0x36d6b4(0x2ae)+'TOKEN\x20not\x20'+_0x36d6b4(0x39e)})),!![];try{const _0x5b07e6=await fetch(_0x36d6b4(0x2e7)+_0x36d6b4(0x20a)+_0x36d6b4(0x2fb)+'t',{'method':_0x36d6b4(0x1b6),'headers':{'Authorization':'Bearer\x20'+_0x538d40,'Content-Type':_0x36d6b4(0x2ee)+_0x3fa191(0x328)+_0x36d6b4(0x3e3)+_0x3fa191(0x177)}}),_0x2970f1=await _0x5b07e6[_0x36d6b4(0x2c5)]();if(!_0x2970f1['ok'])return _0x5765fc['end'](JSON[_0x36d6b4(0x208)]({'ok':![],'error':'Slack\x20reje'+_0x36d6b4(0x3cd)+_0x3fa191(0x188)+(_0x2970f1['error']||'unknown\x20er'+_0x36d6b4(0x1a8))})),!![];let _0x55587d='';if(!_0x2db35f)_0x55587d=_0x36d6b4(0x1c4)+'PP_TOKEN\x20n'+'ot\x20set\x20—\x20S'+_0x36d6b4(0x127)+_0x36d6b4(0x229)+'.';else!_0x2db35f[_0x3fa191(0x3b5)](_0x3fa191(0x28f))&&(_0x55587d='\x20⚠️\x20SLACK_A'+_0x36d6b4(0x17b)+_0x36d6b4(0x2b8)+'refix\x20(exp'+_0x3fa191(0x2c6)+_0x3fa191(0x179)+_0x3fa191(0x3f2)+_0x36d6b4(0x314));_0x5765fc[_0x3fa191(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':!![],'info':'@'+_0x2970f1[_0x3fa191(0x25a)]+_0x3fa191(0x1ed)+_0x2970f1[_0x36d6b4(0x1af)]+(_0x3fa191(0x399)+'\x20')+_0x2970f1['team_id']+',\x20bot_id:\x20'+_0x2970f1[_0x36d6b4(0x2db)]+')'+_0x55587d}));}catch(_0xd14e16){const _0x2ce83b=_0xd14e16 instanceof Error?_0xd14e16[_0x3fa191(0xe2)]:String(_0xd14e16);_0x5765fc[_0x36d6b4(0x2c8)](JSON[_0x36d6b4(0x208)]({'ok':![],'error':'Failed\x20to\x20'+'reach\x20slac'+'k.com/api/'+_0x36d6b4(0x1b9)+'\x20'+_0x2ce83b}));}return!![];}_0x5765fc['end'](JSON['stringify']({'ok':![],'error':'Unknown\x20pl'+_0x36d6b4(0x3a7)}));}catch(_0x20ab65){const _0x1ecd97=_0x20ab65 instanceof Error?_0x20ab65[_0x3fa191(0xe2)]:String(_0x20ab65);_0x5765fc['end'](JSON[_0x3fa191(0x208)]({'ok':![],'error':_0x1ecd97}));}return!![];}return![];}function maskSecret(_0x4c2066){const _0x59ffad=_0x19b6b0,_0x122ee=_0x19b6b0;if(_0x4c2066[_0x59ffad(0xee)]<=0x1*0x1e29+-0xb99+-0x1288)return _0x122ee(0x350);return _0x4c2066['slice'](0x1d26+0x2*-0xa57+0x878*-0x1,-0x1*0xca+0x1585+-0x14b7)+'...'+_0x4c2066[_0x122ee(0x3be)](-(-0x1b88+-0xbd*0x7+0x20b7));}function checkNpmDeps(_0x1f5f0f){const _0x5b0f55=_0x2f6ba1,_0x1eb652=resolve(BOT_ROOT,'node_modul'+'es');return _0x1f5f0f[_0x5b0f55(0x1bc)](_0x21930e=>{const _0x199018=_0x5b0f55;try{return _0x5450d7['existsSync'](resolve(_0x1eb652,_0x21930e[_0x199018(0x39f)]('/')[0x3*-0x477+0x1cf3*0x1+-0xb*0x16a]));}catch{return![];}});}async function testApiKey(_0x21e9bd,_0x721726){const _0x1d682b=_0x19b6b0,_0x3f80bf=_0x19b6b0;try{const _0xacb035=PROVIDERS[_0x1d682b(0x141)](_0x5c69d9=>_0x5c69d9['id']===_0x21e9bd);if(!_0xacb035)return{'ok':![],'error':_0x3f80bf(0x383)+_0x1d682b(0x2a8)};if(_0x721726===_0x1d682b(0xdb)+_0x3f80bf(0x22a)){if(_0x21e9bd===_0x3f80bf(0x10f)||_0x21e9bd===_0x1d682b(0x21b))_0x721726='';else{const _0x3ade84=_0xacb035[_0x1d682b(0xdd)],_0x305cc0=_0x3ade84?process[_0x1d682b(0x3b0)][_0x3ade84]:undefined;if(!_0x305cc0)return{'ok':![],'error':'No\x20stored\x20'+'key\x20availa'+_0x1d682b(0x2a9)};_0x721726=_0x305cc0;}}switch(_0x21e9bd){case _0x1d682b(0x2aa):{const _0xc34bec=await fetch('https://ap'+_0x1d682b(0x297)+_0x1d682b(0x292)+'ls',{'headers':{'Authorization':_0x3f80bf(0x2d2)+_0x721726}});if(!_0xc34bec['ok'])return{'ok':![],'error':_0x1d682b(0x34f)+_0xc34bec[_0x1d682b(0x11a)]+':\x20'+await _0xc34bec[_0x3f80bf(0x189)]()};return{'ok':!![],'model':_0x3f80bf(0x3e2)};}case _0x3f80bf(0x172):{const _0x5d7496=await fetch(_0x1d682b(0x12d)+_0x3f80bf(0x35b)+'nguage.goo'+_0x3f80bf(0x3a3)+_0x1d682b(0x2b3)+_0x1d682b(0x248)+_0x721726);if(!_0x5d7496['ok'])return{'ok':![],'error':_0x3f80bf(0x34f)+_0x5d7496['status']+':\x20'+await _0x5d7496[_0x1d682b(0x189)]()};return{'ok':!![],'model':_0x1d682b(0x384)+_0x1d682b(0x104)};}case _0x1d682b(0x1d8):{const _0x2bb731=await fetch(_0x1d682b(0x369)+_0x1d682b(0x3d6)+'i.nvidia.c'+_0x3f80bf(0x292)+'ls',{'headers':{'Authorization':_0x3f80bf(0x2d2)+_0x721726}});if(!_0x2bb731['ok'])return{'ok':![],'error':'HTTP\x20'+_0x2bb731[_0x3f80bf(0x11a)]+':\x20'+await _0x2bb731['text']()};return{'ok':!![],'model':'meta/llama'+_0x3f80bf(0x22c)+'nstruct'};}case _0x1d682b(0x3bf):{const _0x19938a=await fetch(_0x1d682b(0x23c)+'enrouter.a'+_0x3f80bf(0x1d6)+'odels',{'headers':{'Authorization':_0x1d682b(0x2d2)+_0x721726}});if(!_0x19938a['ok'])return{'ok':![],'error':'HTTP\x20'+_0x19938a['status']+':\x20'+await _0x19938a[_0x1d682b(0x189)]()};return{'ok':!![],'model':'anthropic/'+_0x1d682b(0x113)+_0x1d682b(0x24b)};}case'groq':{const _0x1ec63c=await fetch('https://ap'+_0x3f80bf(0x16a)+_0x1d682b(0x207)+_0x1d682b(0x17e),{'headers':{'Authorization':_0x1d682b(0x2d2)+_0x721726}});if(!_0x1ec63c['ok'])return{'ok':![],'error':_0x1d682b(0x34f)+_0x1ec63c[_0x1d682b(0x11a)]+':\x20'+await _0x1ec63c[_0x3f80bf(0x189)]()};return{'ok':!![],'model':_0x3f80bf(0x2f1)+_0x3f80bf(0x3a8)+_0x1d682b(0x29f)};}case _0x3f80bf(0x10f):{const {execSync:_0x161aa5}=await import(_0x3f80bf(0xe4)+_0x3f80bf(0x287));try{return _0x161aa5(_0x1d682b(0x37a)+'ersion',{'timeout':0x1388,'stdio':'pipe'}),{'ok':!![],'model':'claude-opu'+_0x1d682b(0x146)};}catch{return{'ok':![],'error':_0x1d682b(0x2f8)+_0x3f80bf(0x25e)+'lled\x20or\x20no'+_0x3f80bf(0x196)+'n'};}}case _0x3f80bf(0x185):{const _0x5b6ad9=await fetch(_0x3f80bf(0x2ff)+_0x1d682b(0x109)+_0x1d682b(0x38c)+'odels',{'headers':{'x-api-key':_0x721726,'anthropic-version':_0x1d682b(0x2c2)}});if(!_0x5b6ad9['ok'])return{'ok':![],'error':_0x3f80bf(0x34f)+_0x5b6ad9['status']+':\x20'+(await _0x5b6ad9[_0x1d682b(0x189)]())['substring'](-0x2*-0x859+-0x13d1+-0x11*-0x2f,-0x1d20+-0xaa+-0x45e*-0x7)};return{'ok':!![],'model':'claude-son'+_0x1d682b(0x24b)};}default:return{'ok':![],'error':_0x3f80bf(0xd0)+_0x1d682b(0x3df)+_0x3f80bf(0x304)+'s\x20provider'};}}catch(_0xd2e3a5){return{'ok':![],'error':_0xd2e3a5 instanceof Error?_0xd2e3a5[_0x1d682b(0xe2)]:String(_0xd2e3a5)};}}async function fetchLiveModels(_0x2bf6c7){const _0x2f157e=_0x19b6b0,_0x9c42ed=_0x2f6ba1,_0x36ecfb=process[_0x2f157e(0x3b0)];switch(_0x2bf6c7){case _0x2f157e(0x185):{const _0x2b5e50=_0x36ecfb[_0x2f157e(0x259)+'API_KEY'];if(!_0x2b5e50)return[];const _0x59bb28=await fetch(_0x9c42ed(0x2ff)+'i.anthropi'+_0x9c42ed(0x38c)+'odels',{'headers':{'x-api-key':_0x2b5e50,'anthropic-version':_0x9c42ed(0x2c2)}});if(!_0x59bb28['ok'])return[];const _0x20f81f=await _0x59bb28[_0x2f157e(0x2c5)]();return(_0x20f81f[_0x9c42ed(0x195)]||[])[_0x2f157e(0x235)](_0x11ff00=>_0x11ff00['id']&&!_0x11ff00['id']['includes'](_0x2f157e(0x31e)))[_0x2f157e(0x14e)](_0x1f1dc4=>({'id':_0x1f1dc4['id'],'name':_0x1f1dc4['display_na'+'me']||_0x1f1dc4['id'],'owned_by':_0x9c42ed(0x185)}))[_0x9c42ed(0x245)]((_0x19810b,_0x4d9674)=>_0x19810b['id'][_0x2f157e(0x3d4)+_0x2f157e(0x33f)](_0x4d9674['id']));}case _0x2f157e(0x2aa):{const _0x5c0b6b=_0x36ecfb[_0x2f157e(0x3d0)+_0x9c42ed(0x102)];if(!_0x5c0b6b)return[];const _0x353702=await fetch(_0x2f157e(0x2ff)+_0x2f157e(0x297)+_0x9c42ed(0x292)+'ls',{'headers':{'Authorization':_0x9c42ed(0x2d2)+_0x5c0b6b}});if(!_0x353702['ok'])return[];const _0x17450d=await _0x353702['json'](),_0x448ab9=['gpt-4','gpt-3.5','o1','o3','o4',_0x9c42ed(0x1a1)];return(_0x17450d[_0x2f157e(0x195)]||[])[_0x2f157e(0x235)](_0xe46dee=>_0x448ab9[_0x2f157e(0x360)](_0x3a8254=>_0xe46dee['id']['startsWith'](_0x3a8254)))[_0x2f157e(0x14e)](_0x569175=>({'id':_0x569175['id'],'name':_0x569175['id'],'owned_by':_0x569175['owned_by']||_0x9c42ed(0x2aa)}))[_0x9c42ed(0x245)]((_0x26919e,_0xa2d708)=>_0x26919e['id']['localeComp'+_0x2f157e(0x33f)](_0xa2d708['id']));}case'google':{const _0xd67780=_0x36ecfb[_0x2f157e(0x28e)+'_KEY'];if(!_0xd67780)return[];const _0x45c39c=await fetch('https://ge'+_0x2f157e(0x35b)+_0x2f157e(0x133)+_0x2f157e(0x3a3)+'m/v1beta/m'+_0x2f157e(0x248)+_0xd67780);if(!_0x45c39c['ok'])return[];const _0x4d69b7=await _0x45c39c['json']();return(_0x4d69b7[_0x9c42ed(0x13e)]||[])['filter'](_0x23f8fc=>_0x23f8fc[_0x2f157e(0x162)]&&_0x23f8fc[_0x2f157e(0x1ff)+'enerationM'+_0x9c42ed(0x275)]?.['includes'](_0x9c42ed(0x100)+_0x2f157e(0x26f)))[_0x2f157e(0x14e)](_0x23f58a=>({'id':_0x23f58a[_0x2f157e(0x162)][_0x2f157e(0x244)]('models/',''),'name':_0x23f58a[_0x2f157e(0x119)+'e']||_0x23f58a[_0x2f157e(0x162)][_0x9c42ed(0x244)](_0x2f157e(0x23d),''),'owned_by':_0x9c42ed(0x172)}))[_0x9c42ed(0x245)]((_0xa1bb67,_0x3dfdcd)=>_0xa1bb67['id'][_0x9c42ed(0x3d4)+_0x9c42ed(0x33f)](_0x3dfdcd['id']));}case _0x2f157e(0x2dd):{const _0x2027e3=_0x36ecfb['GROQ_API_K'+'EY'];if(!_0x2027e3)return[];const _0x200ee6=await fetch('https://ap'+_0x2f157e(0x16a)+_0x2f157e(0x207)+_0x2f157e(0x17e),{'headers':{'Authorization':'Bearer\x20'+_0x2027e3}});if(!_0x200ee6['ok'])return[];const _0x3a7f94=await _0x200ee6[_0x9c42ed(0x2c5)]();return(_0x3a7f94[_0x9c42ed(0x195)]||[])[_0x9c42ed(0x235)](_0x6fdd3f=>_0x6fdd3f['id']&&_0x6fdd3f['active']!==![])[_0x2f157e(0x14e)](_0x4132cb=>({'id':_0x4132cb['id'],'name':_0x4132cb['id'],'owned_by':_0x4132cb[_0x9c42ed(0x1ce)]||_0x2f157e(0x2dd)}))[_0x9c42ed(0x245)]((_0x38ce6a,_0x173815)=>_0x38ce6a['id']['localeComp'+_0x9c42ed(0x33f)](_0x173815['id']));}case _0x9c42ed(0x1d8):{const _0x42aefe=_0x36ecfb['NVIDIA_API'+'_KEY'];if(!_0x42aefe)return[];const _0x4d3f79=await fetch(_0x2f157e(0x369)+'tegrate.ap'+_0x2f157e(0x11c)+_0x9c42ed(0x292)+'ls',{'headers':{'Authorization':_0x2f157e(0x2d2)+_0x42aefe}});if(!_0x4d3f79['ok'])return[];const _0x509b95=await _0x4d3f79[_0x9c42ed(0x2c5)]();return(_0x509b95[_0x9c42ed(0x195)]||[])[_0x9c42ed(0x14e)](_0x4cd636=>({'id':_0x4cd636['id'],'name':_0x4cd636['id'],'owned_by':_0x4cd636[_0x2f157e(0x1ce)]||_0x9c42ed(0x1d8)}))[_0x2f157e(0x245)]((_0x82aa47,_0x560d41)=>_0x82aa47['id'][_0x2f157e(0x3d4)+_0x9c42ed(0x33f)](_0x560d41['id']));}case _0x9c42ed(0x3bf):{const _0x3c27d0=_0x36ecfb[_0x2f157e(0x260)+_0x2f157e(0x27d)];if(!_0x3c27d0)return[];const _0x1d4bac=await fetch('https://op'+_0x2f157e(0x249)+'i/api/v1/m'+_0x2f157e(0x1ee),{'headers':{'Authorization':_0x2f157e(0x2d2)+_0x3c27d0}});if(!_0x1d4bac['ok'])return[];const _0x3f2662=await _0x1d4bac[_0x9c42ed(0x2c5)]();return(_0x3f2662[_0x2f157e(0x195)]||[])['slice'](-0xb6d+0x3f1*0x5+-0x14*0x6a,-0x2d1*-0xa+-0x300+-0x18c6)['map'](_0xf25d4b=>({'id':_0xf25d4b['id'],'name':_0xf25d4b[_0x9c42ed(0x162)]||_0xf25d4b['id'],'owned_by':_0x2f157e(0x3bf)}))[_0x2f157e(0x245)]((_0x284ebd,_0x23b84c)=>_0x284ebd['id']['localeComp'+'are'](_0x23b84c['id']));}default:return[];}}
|