alvin-bot 5.7.0 → 5.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +25 -31
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -174
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -583
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -86
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1902
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,313 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Heartbeat Service — Provider health monitoring with auto-failover.
|
|
3
|
-
*
|
|
4
|
-
* Periodically pings providers (tiny completion request) to detect outages.
|
|
5
|
-
* If the primary provider fails, auto-switches to the first healthy fallback.
|
|
6
|
-
* When the primary recovers, switches back automatically.
|
|
7
|
-
*
|
|
8
|
-
* v4.15.2 — Sleep-aware: detects macOS/Linux suspend via wall-clock drift
|
|
9
|
-
* (gap between expected and actual heartbeat tick > 2× the interval). After
|
|
10
|
-
* wake, gives providers a grace period before counting failures, and schedules
|
|
11
|
-
* a quick recovery probe 60s after any failover so recovery doesn't wait for
|
|
12
|
-
* the full 5-minute cycle.
|
|
13
|
-
*
|
|
14
|
-
* The heartbeat provider (Groq by default) is always registered as the
|
|
15
|
-
* last-resort fallback — free, fast, reliable.
|
|
16
|
-
*/
|
|
17
|
-
import { getRegistry } from "../engine.js";
|
|
18
|
-
import { config } from "../config.js";
|
|
19
|
-
// ── Configuration ───────────────────────────────────────────────────────────
|
|
20
|
-
const HEARTBEAT_INTERVAL_MS = 5 * 60 * 1000; // Check every 5 minutes
|
|
21
|
-
const HEARTBEAT_TIMEOUT_MS = 15_000; // 15s timeout per check
|
|
22
|
-
const FAIL_THRESHOLD = 2; // Switch after 2 consecutive failures
|
|
23
|
-
const RECOVERY_THRESHOLD = 1; // Switch back after 1 success
|
|
24
|
-
/** After detecting macOS sleep/wake, skip failure accounting for this long.
|
|
25
|
-
* Gives network, DNS, and OAuth token refresh time to settle. */
|
|
26
|
-
const POST_SLEEP_GRACE_MS = 60_000; // 60s grace after wake
|
|
27
|
-
/** After a failover, schedule an extra recovery probe after this delay
|
|
28
|
-
* instead of waiting for the full HEARTBEAT_INTERVAL_MS cycle. */
|
|
29
|
-
const QUICK_RECOVERY_DELAY_MS = 60_000; // 60s after failover → re-check
|
|
30
|
-
// Default heartbeat/fallback provider (free, no key needed for check)
|
|
31
|
-
const HEARTBEAT_PROVIDER = "groq";
|
|
32
|
-
// ── State ───────────────────────────────────────────────────────────────────
|
|
33
|
-
const state = {
|
|
34
|
-
providers: new Map(),
|
|
35
|
-
intervalId: null,
|
|
36
|
-
isRunning: false,
|
|
37
|
-
originalPrimary: "",
|
|
38
|
-
wasFailedOver: false,
|
|
39
|
-
lastRunAt: 0,
|
|
40
|
-
graceUntil: 0,
|
|
41
|
-
quickRecoveryTimer: null,
|
|
42
|
-
};
|
|
43
|
-
// ── Public API ──────────────────────────────────────────────────────────────
|
|
44
|
-
/**
|
|
45
|
-
* Start the heartbeat monitor.
|
|
46
|
-
*/
|
|
47
|
-
export function startHeartbeat() {
|
|
48
|
-
if (state.isRunning)
|
|
49
|
-
return;
|
|
50
|
-
const registry = getRegistry();
|
|
51
|
-
state.originalPrimary = registry.getActiveKey();
|
|
52
|
-
state.isRunning = true;
|
|
53
|
-
state.lastRunAt = Date.now();
|
|
54
|
-
state.graceUntil = 0;
|
|
55
|
-
// Initial health state for all providers
|
|
56
|
-
// We'll check providers in the fallback chain
|
|
57
|
-
const chain = [
|
|
58
|
-
config.primaryProvider,
|
|
59
|
-
...config.fallbackProviders,
|
|
60
|
-
].filter((v, i, a) => a.indexOf(v) === i); // dedupe
|
|
61
|
-
for (const key of chain) {
|
|
62
|
-
state.providers.set(key, {
|
|
63
|
-
key,
|
|
64
|
-
healthy: true, // assume healthy until proven otherwise
|
|
65
|
-
lastCheck: 0,
|
|
66
|
-
lastLatencyMs: 0,
|
|
67
|
-
failCount: 0,
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
console.log(`💓 Heartbeat monitor started (${HEARTBEAT_INTERVAL_MS / 1000}s interval, ${chain.length} providers)`);
|
|
71
|
-
// Run first check after 30s (let bot fully start)
|
|
72
|
-
setTimeout(() => {
|
|
73
|
-
runHeartbeat();
|
|
74
|
-
state.intervalId = setInterval(runHeartbeat, HEARTBEAT_INTERVAL_MS);
|
|
75
|
-
// .unref() so this interval alone doesn't keep the process alive during
|
|
76
|
-
// graceful shutdown — the bot's main loop (grammy, platforms) keeps it
|
|
77
|
-
// running, and once those stop we want the process to exit cleanly.
|
|
78
|
-
state.intervalId?.unref?.();
|
|
79
|
-
}, 30_000);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Stop the heartbeat monitor.
|
|
83
|
-
*/
|
|
84
|
-
export function stopHeartbeat() {
|
|
85
|
-
if (state.intervalId) {
|
|
86
|
-
clearInterval(state.intervalId);
|
|
87
|
-
state.intervalId = null;
|
|
88
|
-
}
|
|
89
|
-
if (state.quickRecoveryTimer) {
|
|
90
|
-
clearTimeout(state.quickRecoveryTimer);
|
|
91
|
-
state.quickRecoveryTimer = null;
|
|
92
|
-
}
|
|
93
|
-
state.isRunning = false;
|
|
94
|
-
console.log("💓 Heartbeat monitor stopped");
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Get current health status of all monitored providers.
|
|
98
|
-
*/
|
|
99
|
-
export function getHealthStatus() {
|
|
100
|
-
return Array.from(state.providers.values()).map(p => ({
|
|
101
|
-
key: p.key,
|
|
102
|
-
healthy: p.healthy,
|
|
103
|
-
latencyMs: p.lastLatencyMs,
|
|
104
|
-
failCount: p.failCount,
|
|
105
|
-
lastCheck: p.lastCheck ? new Date(p.lastCheck).toISOString() : "never",
|
|
106
|
-
lastError: p.lastError,
|
|
107
|
-
}));
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Get the fallback order (user-configurable).
|
|
111
|
-
*/
|
|
112
|
-
export function getFallbackOrder() {
|
|
113
|
-
return config.fallbackProviders;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Whether we're currently failed over from the primary.
|
|
117
|
-
*/
|
|
118
|
-
export function isFailedOver() {
|
|
119
|
-
return state.wasFailedOver;
|
|
120
|
-
}
|
|
121
|
-
// ── Internal ────────────────────────────────────────────────────────────────
|
|
122
|
-
async function runHeartbeat() {
|
|
123
|
-
const registry = getRegistry();
|
|
124
|
-
const now = Date.now();
|
|
125
|
-
// ── Sleep detection ────────────────────────────────────────────────────
|
|
126
|
-
// Node.js setInterval pauses during macOS/Linux suspend. If the wall-clock
|
|
127
|
-
// gap since the last tick exceeds 2× the interval, the machine was asleep.
|
|
128
|
-
// In that case, providers (especially CLI-based ones like claude-sdk) need
|
|
129
|
-
// time to warm up — network re-connects, OAuth tokens refresh, DNS caches
|
|
130
|
-
// re-populate. Without a grace period, the first probe after wake almost
|
|
131
|
-
// always fails, triggering a premature failover to Ollama.
|
|
132
|
-
const elapsed = now - state.lastRunAt;
|
|
133
|
-
const justWoke = state.lastRunAt > 0 && elapsed > HEARTBEAT_INTERVAL_MS * 2;
|
|
134
|
-
if (justWoke) {
|
|
135
|
-
const sleepDuration = Math.round(elapsed / 60_000);
|
|
136
|
-
console.log(`💓 😴 Sleep detected (~${sleepDuration}min gap). Grace period ${POST_SLEEP_GRACE_MS / 1000}s — failures won't count.`);
|
|
137
|
-
state.graceUntil = now + POST_SLEEP_GRACE_MS;
|
|
138
|
-
// Invalidate isAvailable() caches on all providers so the first probe
|
|
139
|
-
// after wake doesn't serve a 7-hour-old cached "unavailable" result.
|
|
140
|
-
for (const [key] of state.providers) {
|
|
141
|
-
const provider = registry.get(key);
|
|
142
|
-
if (provider && typeof provider.invalidateAvailabilityCache === "function") {
|
|
143
|
-
provider.invalidateAvailabilityCache();
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
// Reset fail counters — stale failures from before sleep are meaningless.
|
|
147
|
-
for (const [, health] of state.providers) {
|
|
148
|
-
if (!health.healthy) {
|
|
149
|
-
health.failCount = 0;
|
|
150
|
-
health.healthy = true;
|
|
151
|
-
console.log(`💓 😴 Reset ${health.key} to healthy (post-sleep clean slate)`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
state.lastRunAt = now;
|
|
156
|
-
const inGracePeriod = now < state.graceUntil;
|
|
157
|
-
// ── Provider health checks ─────────────────────────────────────────────
|
|
158
|
-
for (const [key, health] of state.providers) {
|
|
159
|
-
const provider = registry.get(key);
|
|
160
|
-
if (!provider)
|
|
161
|
-
continue;
|
|
162
|
-
// Providers with an on-demand lifecycle (local runners: Ollama, LM
|
|
163
|
-
// Studio, llama.cpp, …) are not pinged periodically — they're off
|
|
164
|
-
// until we actively boot them during failover. Mark as always-healthy
|
|
165
|
-
// so they remain a valid failover target.
|
|
166
|
-
if (provider.lifecycle) {
|
|
167
|
-
health.healthy = true;
|
|
168
|
-
health.lastCheck = Date.now();
|
|
169
|
-
health.lastLatencyMs = 0;
|
|
170
|
-
health.failCount = 0;
|
|
171
|
-
health.lastError = undefined;
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
const start = Date.now();
|
|
175
|
-
try {
|
|
176
|
-
// Quick availability check first
|
|
177
|
-
const available = await Promise.race([
|
|
178
|
-
provider.isAvailable(),
|
|
179
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), HEARTBEAT_TIMEOUT_MS)),
|
|
180
|
-
]);
|
|
181
|
-
if (!available) {
|
|
182
|
-
throw new Error("Provider reported unavailable");
|
|
183
|
-
}
|
|
184
|
-
// Tiny completion request to verify actual functionality
|
|
185
|
-
const testResult = await Promise.race([
|
|
186
|
-
pingProvider(provider, key),
|
|
187
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), HEARTBEAT_TIMEOUT_MS)),
|
|
188
|
-
]);
|
|
189
|
-
// Success
|
|
190
|
-
health.healthy = true;
|
|
191
|
-
health.lastLatencyMs = Date.now() - start;
|
|
192
|
-
health.lastCheck = Date.now();
|
|
193
|
-
health.lastError = undefined;
|
|
194
|
-
// Recovery check: if primary was down and is back
|
|
195
|
-
if (health.failCount > 0) {
|
|
196
|
-
console.log(`💓 ${key}: recovered (${health.lastLatencyMs}ms)`);
|
|
197
|
-
}
|
|
198
|
-
health.failCount = 0;
|
|
199
|
-
}
|
|
200
|
-
catch (err) {
|
|
201
|
-
health.lastLatencyMs = Date.now() - start;
|
|
202
|
-
health.lastCheck = Date.now();
|
|
203
|
-
health.lastError = err instanceof Error ? err.message : String(err);
|
|
204
|
-
// During the post-sleep grace period, log the failure but don't
|
|
205
|
-
// increment the counter — transient post-wake unavailability is
|
|
206
|
-
// expected and should not trigger a failover.
|
|
207
|
-
if (inGracePeriod) {
|
|
208
|
-
console.log(`💓 😴 ${key}: probe failed during grace period (${health.lastError}) — not counting`);
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
health.failCount++;
|
|
212
|
-
if (health.failCount >= FAIL_THRESHOLD) {
|
|
213
|
-
health.healthy = false;
|
|
214
|
-
console.log(`💓 ❌ ${key}: unhealthy (${health.failCount} failures: ${health.lastError})`);
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
console.log(`💓 ⚠️ ${key}: failure ${health.failCount}/${FAIL_THRESHOLD} (${health.lastError})`);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
// Auto-failover logic
|
|
222
|
-
await handleFailover(registry);
|
|
223
|
-
}
|
|
224
|
-
async function pingProvider(provider, key) {
|
|
225
|
-
// For CLI-based providers, just check availability (no full query needed)
|
|
226
|
-
if (key === "claude-sdk" || key === "codex-cli") {
|
|
227
|
-
const available = await provider.isAvailable();
|
|
228
|
-
return available ? "ok" : "unavailable";
|
|
229
|
-
}
|
|
230
|
-
// For OpenAI-compatible: tiny completion
|
|
231
|
-
let text = "";
|
|
232
|
-
for await (const chunk of provider.query({
|
|
233
|
-
prompt: "Hi",
|
|
234
|
-
systemPrompt: "Reply with exactly: ok",
|
|
235
|
-
history: [],
|
|
236
|
-
})) {
|
|
237
|
-
if (chunk.type === "text")
|
|
238
|
-
text = chunk.text;
|
|
239
|
-
if (chunk.type === "done")
|
|
240
|
-
return text || "ok";
|
|
241
|
-
if (chunk.type === "error")
|
|
242
|
-
throw new Error(chunk.error);
|
|
243
|
-
}
|
|
244
|
-
return text || "ok";
|
|
245
|
-
}
|
|
246
|
-
async function handleFailover(registry) {
|
|
247
|
-
const primaryHealth = state.providers.get(state.originalPrimary);
|
|
248
|
-
const currentKey = registry.getActiveKey();
|
|
249
|
-
// Case 1: Primary is down → switch to first healthy fallback
|
|
250
|
-
if (primaryHealth && !primaryHealth.healthy && currentKey === state.originalPrimary) {
|
|
251
|
-
const fallbackOrder = config.fallbackProviders;
|
|
252
|
-
for (const fbKey of fallbackOrder) {
|
|
253
|
-
const fbHealth = state.providers.get(fbKey);
|
|
254
|
-
if (!fbHealth?.healthy)
|
|
255
|
-
continue;
|
|
256
|
-
const fbProvider = registry.get(fbKey);
|
|
257
|
-
if (!fbProvider)
|
|
258
|
-
continue;
|
|
259
|
-
// Providers with a lifecycle (local runners) must be booted before
|
|
260
|
-
// the switch. If boot fails, skip and try the next fallback.
|
|
261
|
-
if (fbProvider.lifecycle) {
|
|
262
|
-
console.log(`💓 🔄 Auto-failover: ${state.originalPrimary} → ${fbKey} — booting ${fbKey}…`);
|
|
263
|
-
const ok = await fbProvider.lifecycle.ensureRunning();
|
|
264
|
-
if (!ok) {
|
|
265
|
-
console.log(`💓 ⚠️ ${fbKey} boot failed — skipping`);
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
console.log(`💓 🔄 Auto-failover: ${state.originalPrimary} → ${fbKey}`);
|
|
271
|
-
}
|
|
272
|
-
registry.switchTo(fbKey);
|
|
273
|
-
state.wasFailedOver = true;
|
|
274
|
-
// v4.15.2 — Schedule a quick recovery probe so we don't sit on
|
|
275
|
-
// the fallback for a full 5 minutes when the primary might already
|
|
276
|
-
// be back. Clear any previous pending timer first.
|
|
277
|
-
scheduleQuickRecovery();
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
console.log("💓 ⚠️ All providers unhealthy — staying on primary");
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
// Case 2: Primary recovered → switch back, tearing down any lifecycle-
|
|
284
|
-
// managed fallback we booted during the outage.
|
|
285
|
-
if (primaryHealth?.healthy && state.wasFailedOver && currentKey !== state.originalPrimary) {
|
|
286
|
-
const currentProvider = registry.get(currentKey);
|
|
287
|
-
console.log(`💓 ✅ Primary recovered — switching back to ${state.originalPrimary}`);
|
|
288
|
-
registry.switchTo(state.originalPrimary);
|
|
289
|
-
state.wasFailedOver = false;
|
|
290
|
-
if (currentProvider?.lifecycle) {
|
|
291
|
-
console.log(`💓 🧹 Tearing down ${currentKey} daemon + unloading model`);
|
|
292
|
-
await currentProvider.lifecycle.ensureStopped();
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Schedule an extra heartbeat probe after QUICK_RECOVERY_DELAY_MS. This runs
|
|
298
|
-
* in addition to the regular 5-minute interval — its sole purpose is to detect
|
|
299
|
-
* primary recovery quickly after a failover instead of waiting up to 5 minutes.
|
|
300
|
-
*/
|
|
301
|
-
function scheduleQuickRecovery() {
|
|
302
|
-
if (state.quickRecoveryTimer) {
|
|
303
|
-
clearTimeout(state.quickRecoveryTimer);
|
|
304
|
-
}
|
|
305
|
-
console.log(`💓 ⏱️ Quick recovery probe scheduled in ${QUICK_RECOVERY_DELAY_MS / 1000}s`);
|
|
306
|
-
state.quickRecoveryTimer = setTimeout(async () => {
|
|
307
|
-
state.quickRecoveryTimer = null;
|
|
308
|
-
if (!state.wasFailedOver || !state.isRunning)
|
|
309
|
-
return;
|
|
310
|
-
console.log("💓 ⏱️ Quick recovery probe firing…");
|
|
311
|
-
await runHeartbeat();
|
|
312
|
-
}, QUICK_RECOVERY_DELAY_MS);
|
|
313
|
-
}
|
|
1
|
+
const _0x20d696=_0x286e;function _0x286e(_0x378688,_0x280b9c){_0x378688=_0x378688-(0x10cc+0x336+-0x1219);const _0x330db6=_0x5e30();let _0x536ba8=_0x330db6[_0x378688];if(_0x286e['dKjzZH']===undefined){var _0x1e2a1f=function(_0x520b9a){const _0x4eeefd='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2b9ee5='',_0x1b02df='',_0x31adcd=_0x2b9ee5+_0x1e2a1f;for(let _0x5ec75b=0x2619+-0x1*0x5f2+-0x2027*0x1,_0x5a7313,_0x76b62,_0x205340=0x2f5*-0x5+0x8b6+0x1*0x613;_0x76b62=_0x520b9a['charAt'](_0x205340++);~_0x76b62&&(_0x5a7313=_0x5ec75b%(-0x26d4+0x85f*0x1+0x1e79)?_0x5a7313*(-0x175*-0x11+-0xd1f+0x1*-0xb66)+_0x76b62:_0x76b62,_0x5ec75b++%(0x93*0x21+-0x427*0x3+-0x67a))?_0x2b9ee5+=_0x31adcd['charCodeAt'](_0x205340+(0x1ff5+-0x1e3a+-0x1*0x1b1))-(-0x3b9*0x5+-0x48a*0x6+0x2b3*0x11)!==0xb68+0x815*0x2+-0x1b92*0x1?String['fromCharCode'](0x2*-0x4ae+0x1*0x12ad+-0xd5*0xa&_0x5a7313>>(-(0x1*-0x454+0x5*-0x1b+0x4dd)*_0x5ec75b&0x295*0x9+0x367*0x6+-0x2ba1)):_0x5ec75b:0xac1+-0x387+-0x73a){_0x76b62=_0x4eeefd['indexOf'](_0x76b62);}for(let _0x2ad168=0x1*0x1887+0x1ad4+-0x1*0x335b,_0x27030b=_0x2b9ee5['length'];_0x2ad168<_0x27030b;_0x2ad168++){_0x1b02df+='%'+('00'+_0x2b9ee5['charCodeAt'](_0x2ad168)['toString'](0x1bef+0x3f9+-0x1fd8))['slice'](-(0x15*0x25+0x14cc+-0x17d3));}return decodeURIComponent(_0x1b02df);};_0x286e['QuLQIf']=_0x1e2a1f,_0x286e['xWpnWa']={},_0x286e['dKjzZH']=!![];}const _0x5b0722=_0x330db6[-0x651+0x1*0xd33+-0x6e2],_0x5bcd2e=_0x378688+_0x5b0722,_0x5c9829=_0x286e['xWpnWa'][_0x5bcd2e];if(!_0x5c9829){const _0x1034c6=function(_0x2f3396){this['yZoFzc']=_0x2f3396,this['jnrHWR']=[-0x58a*0x1+-0x1*0xbc1+-0xc*-0x171,-0x17*-0x17b+0xd36+-0x2f43,0x285*-0x1+0x727+0x2*-0x251],this['QXhMQf']=function(){return'newState';},this['belukx']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['aQULjR']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x1034c6['prototype']['giLSyN']=function(){const _0x54baac=new RegExp(this['belukx']+this['aQULjR']),_0x97d3fb=_0x54baac['test'](this['QXhMQf']['toString']())?--this['jnrHWR'][0x1*0x22ae+0x17cd*-0x1+-0xae0]:--this['jnrHWR'][0x1d84*0x1+-0x1bdf+-0x1a5*0x1];return this['jTTHEu'](_0x97d3fb);},_0x1034c6['prototype']['jTTHEu']=function(_0x3a7d5e){if(!Boolean(~_0x3a7d5e))return _0x3a7d5e;return this['aPDfix'](this['yZoFzc']);},_0x1034c6['prototype']['aPDfix']=function(_0x1ca401){for(let _0x546be9=0x175+-0x23f6+-0x79*-0x49,_0x36d1e3=this['jnrHWR']['length'];_0x546be9<_0x36d1e3;_0x546be9++){this['jnrHWR']['push'](Math['round'](Math['random']())),_0x36d1e3=this['jnrHWR']['length'];}return _0x1ca401(this['jnrHWR'][-0x125d+0xa*-0x289+0x169*0x1f]);},new _0x1034c6(_0x286e)['giLSyN'](),_0x536ba8=_0x286e['QuLQIf'](_0x536ba8),_0x286e['xWpnWa'][_0x5bcd2e]=_0x536ba8;}else _0x536ba8=_0x5c9829;return _0x536ba8;}(function(_0x50bcff,_0x58b80d){const _0x47d940=_0x286e,_0x7bd378=_0x286e,_0x2ce07b=_0x50bcff();while(!![]){try{const _0x1d1bc7=-parseInt(_0x47d940(0x1ec))/(-0x84*-0x14+0x4f7*0x7+-0x2d10)*(-parseInt(_0x7bd378(0x240))/(0x4*0x293+-0x25e4+0x1b9a))+parseInt(_0x7bd378(0x1fa))/(0x1c5e*0x1+-0x50e+-0x174d)+parseInt(_0x47d940(0x230))/(-0x1041+-0x1*-0x19b7+0x6*-0x193)*(parseInt(_0x47d940(0x25d))/(-0x1bf2+-0x29a*0xa+0x35fb))+parseInt(_0x7bd378(0x22f))/(0x12a3+-0x2*-0xc2b+-0x2af3)*(parseInt(_0x7bd378(0x256))/(0xac9+-0x1a7d+0xfbb))+-parseInt(_0x47d940(0x1f2))/(0x1f60+0x18bb+-0x3813)+parseInt(_0x7bd378(0x22b))/(0x101*0x16+0x1844*0x1+-0x47*0xa7)*(parseInt(_0x7bd378(0x1ea))/(0xe96*-0x1+0x2526+-0x1686))+-parseInt(_0x47d940(0x20e))/(0xb2*-0x13+-0xdd4+0x1b15);if(_0x1d1bc7===_0x58b80d)break;else _0x2ce07b['push'](_0x2ce07b['shift']());}catch(_0x567d54){_0x2ce07b['push'](_0x2ce07b['shift']());}}}(_0x5e30,0x6*-0x3ac6+0x117618+-0x1ead3));const _0xf080d0=(function(){let _0x1946c6=!![];return function(_0x10bf78,_0x13db4a){const _0x4943e4=_0x1946c6?function(){const _0x23ae73=_0x286e;if(_0x13db4a){const _0x3b3269=_0x13db4a[_0x23ae73(0x209)](_0x10bf78,arguments);return _0x13db4a=null,_0x3b3269;}}:function(){};return _0x1946c6=![],_0x4943e4;};}()),_0x2dd261=_0xf080d0(this,function(){const _0x3a96ac=_0x286e,_0xdaf5d4=_0x286e;return _0x2dd261[_0x3a96ac(0x200)]()['search'](_0xdaf5d4(0x251)+'+$')[_0x3a96ac(0x200)]()[_0xdaf5d4(0x23f)+'r'](_0x2dd261)[_0xdaf5d4(0x207)]('(((.+)+)+)'+'+$');});_0x2dd261();import{getRegistry}from'../engine.js';import{config}from'../config.js';const HEARTBEAT_INTERVAL_MS=(-0x2*-0x45b+0x4*0x563+-0x1e3d)*(0x85f*0x1+-0x1f50+-0x11*-0x15d)*(0x53c+0x1*-0x13ac+-0x4*-0x496),HEARTBEAT_TIMEOUT_MS=-0x9d*-0x1f+0x4932+-0x219d*0x1,FAIL_THRESHOLD=-0x1*0x70c+-0x2258+0x2966,RECOVERY_THRESHOLD=-0x393*-0x5+0x17ff*-0x1+0x3*0x20b,POST_SLEEP_GRACE_MS=0x1*-0x12af2+0x17efd+0x9655,QUICK_RECOVERY_DELAY_MS=0x23*0x667+0x123ef*0x1+-0x119a4,HEARTBEAT_PROVIDER=_0x20d696(0x239),state={'providers':new Map(),'intervalId':null,'isRunning':![],'originalPrimary':'','wasFailedOver':![],'lastRunAt':0x0,'graceUntil':0x0,'quickRecoveryTimer':null};export function startHeartbeat(){const _0x2f9740=_0x20d696,_0x2e1dc6=_0x20d696;if(state[_0x2f9740(0x238)])return;const _0x50f752=getRegistry();state[_0x2f9740(0x1f5)+'imary']=_0x50f752[_0x2f9740(0x1f9)+'ey'](),state[_0x2e1dc6(0x238)]=!![],state[_0x2e1dc6(0x22c)]=Date[_0x2f9740(0x213)](),state['graceUntil']=0x1*-0x454+0x5*-0x1b+0x4db;const _0x4bbedb=[config[_0x2e1dc6(0x234)+_0x2e1dc6(0x220)],...config[_0x2e1dc6(0x203)+'oviders']][_0x2f9740(0x249)]((_0x378688,_0x280b9c,_0x330db6)=>_0x330db6[_0x2e1dc6(0x259)](_0x378688)===_0x280b9c);for(const _0x536ba8 of _0x4bbedb){state[_0x2e1dc6(0x1fb)][_0x2f9740(0x228)](_0x536ba8,{'key':_0x536ba8,'healthy':!![],'lastCheck':0x0,'lastLatencyMs':0x0,'failCount':0x0});}console[_0x2f9740(0x25a)](_0x2e1dc6(0x257)+_0x2e1dc6(0x248)+'started\x20('+HEARTBEAT_INTERVAL_MS/(0x295*0x9+0x367*0x6+-0x27bf)+(_0x2e1dc6(0x218)+',\x20')+_0x4bbedb[_0x2e1dc6(0x20d)]+('\x20providers'+')')),setTimeout(()=>{const _0x2135d1=_0x2f9740,_0x2bb74a=_0x2f9740;runHeartbeat(),state[_0x2135d1(0x21a)]=setInterval(runHeartbeat,HEARTBEAT_INTERVAL_MS),state[_0x2135d1(0x21a)]?.[_0x2bb74a(0x1ef)]?.();},0x4083+-0x1527+0x49d4);}export function stopHeartbeat(){const _0x2792ae=_0x20d696,_0x16ea87=_0x20d696;state[_0x2792ae(0x21a)]&&(clearInterval(state['intervalId']),state[_0x2792ae(0x21a)]=null),state['quickRecov'+'eryTimer']&&(clearTimeout(state['quickRecov'+_0x16ea87(0x1f1)]),state[_0x16ea87(0x23d)+_0x16ea87(0x1f1)]=null),state[_0x16ea87(0x238)]=![],console['log'](_0x16ea87(0x257)+'t\x20monitor\x20'+_0x2792ae(0x1f7));}export function getHealthStatus(){const _0x2b4ea7=_0x20d696,_0x7fb576=_0x20d696;return Array[_0x2b4ea7(0x252)](state[_0x7fb576(0x1fb)]['values']())['map'](_0x1e2a1f=>({'key':_0x1e2a1f[_0x7fb576(0x25b)],'healthy':_0x1e2a1f[_0x2b4ea7(0x204)],'latencyMs':_0x1e2a1f[_0x2b4ea7(0x24c)+_0x2b4ea7(0x217)],'failCount':_0x1e2a1f[_0x2b4ea7(0x237)],'lastCheck':_0x1e2a1f['lastCheck']?new Date(_0x1e2a1f[_0x7fb576(0x1fc)])['toISOStrin'+'g']():_0x2b4ea7(0x24e),'lastError':_0x1e2a1f[_0x2b4ea7(0x250)]}));}export function getFallbackOrder(){const _0x2f9d8c=_0x20d696,_0x18a72c=_0x20d696;return config[_0x2f9d8c(0x203)+_0x18a72c(0x205)];}export function isFailedOver(){const _0x563d81=_0x20d696,_0x186d97=_0x20d696;return state[_0x563d81(0x216)+_0x186d97(0x226)];}async function runHeartbeat(){const _0xdf50e1=_0x20d696,_0x4a0228=_0x20d696,_0x5b0722=getRegistry(),_0x5bcd2e=Date[_0xdf50e1(0x213)](),_0x5c9829=_0x5bcd2e-state['lastRunAt'],_0x520b9a=state[_0x4a0228(0x22c)]>0x1*0x1887+0x1ad4+-0x1*0x335b&&_0x5c9829>HEARTBEAT_INTERVAL_MS*(0x1bef+0x3f9+-0x1fe6);if(_0x520b9a){const _0x2b9ee5=Math['round'](_0x5c9829/(0x54*0x6f+0xf989+-0x3395));console[_0x4a0228(0x25a)](_0x4a0228(0x20f)+'detected\x20('+'~'+_0x2b9ee5+(_0x4a0228(0x247)+_0xdf50e1(0x245)+_0xdf50e1(0x25c))+POST_SLEEP_GRACE_MS/(-0x651+0x1*0xd33+-0x2fa)+(_0xdf50e1(0x25e)+'es\x20won\x27t\x20c'+_0x4a0228(0x210))),state['graceUntil']=_0x5bcd2e+POST_SLEEP_GRACE_MS;for(const [_0x1b02df]of state[_0xdf50e1(0x1fb)]){const _0x31adcd=_0x5b0722[_0x4a0228(0x1ed)](_0x1b02df);_0x31adcd&&typeof _0x31adcd[_0x4a0228(0x231)+'Availabili'+_0x4a0228(0x21e)]===_0x4a0228(0x253)&&_0x31adcd[_0xdf50e1(0x231)+_0xdf50e1(0x23a)+'tyCache']();}for(const [,_0x5ec75b]of state[_0x4a0228(0x1fb)]){!_0x5ec75b['healthy']&&(_0x5ec75b[_0xdf50e1(0x237)]=-0x58a*0x1+-0x1*0xbc1+-0x13*-0xe9,_0x5ec75b[_0xdf50e1(0x204)]=!![],console['log'](_0x4a0228(0x24f)+_0x5ec75b[_0x4a0228(0x25b)]+('\x20to\x20health'+_0x4a0228(0x22d)+_0x4a0228(0x222)+_0x4a0228(0x1ee))));}}state[_0x4a0228(0x22c)]=_0x5bcd2e;const _0x4eeefd=_0x5bcd2e<state['graceUntil'];for(const [_0x5a7313,_0x76b62]of state[_0x4a0228(0x1fb)]){const _0x205340=_0x5b0722[_0x4a0228(0x1ed)](_0x5a7313);if(!_0x205340)continue;if(_0x205340[_0xdf50e1(0x254)]){_0x76b62[_0xdf50e1(0x204)]=!![],_0x76b62[_0x4a0228(0x1fc)]=Date[_0xdf50e1(0x213)](),_0x76b62[_0xdf50e1(0x24c)+'yMs']=-0x17*-0x17b+0xd36+-0x2f43,_0x76b62[_0xdf50e1(0x237)]=0x285*-0x1+0x727+0x2*-0x251,_0x76b62['lastError']=undefined;continue;}const _0x2ad168=Date[_0xdf50e1(0x213)]();try{const _0x27030b=await Promise[_0x4a0228(0x24b)]([_0x205340[_0xdf50e1(0x201)+'e'](),new Promise((_0x2f3396,_0x54baac)=>setTimeout(()=>_0x54baac(new Error(_0xdf50e1(0x23b))),HEARTBEAT_TIMEOUT_MS))]);if(!_0x27030b)throw new Error('Provider\x20r'+_0x4a0228(0x255)+_0x4a0228(0x206));const _0x1034c6=await Promise[_0x4a0228(0x24b)]([pingProvider(_0x205340,_0x5a7313),new Promise((_0x97d3fb,_0x3a7d5e)=>setTimeout(()=>_0x3a7d5e(new Error(_0x4a0228(0x23b))),HEARTBEAT_TIMEOUT_MS))]);_0x76b62['healthy']=!![],_0x76b62['lastLatenc'+'yMs']=Date[_0x4a0228(0x213)]()-_0x2ad168,_0x76b62[_0xdf50e1(0x1fc)]=Date[_0x4a0228(0x213)](),_0x76b62[_0x4a0228(0x250)]=undefined,_0x76b62[_0x4a0228(0x237)]>0x1*0x22ae+0x17cd*-0x1+-0xae1&&console[_0xdf50e1(0x25a)]('💓\x20'+_0x5a7313+(_0x4a0228(0x233)+_0xdf50e1(0x243))+_0x76b62[_0x4a0228(0x24c)+_0x4a0228(0x217)]+'ms)'),_0x76b62['failCount']=0x1d84*0x1+-0x1bdf+-0x1a5*0x1;}catch(_0x1ca401){_0x76b62[_0x4a0228(0x24c)+_0x4a0228(0x217)]=Date['now']()-_0x2ad168,_0x76b62[_0x4a0228(0x1fc)]=Date[_0x4a0228(0x213)](),_0x76b62[_0xdf50e1(0x250)]=_0x1ca401 instanceof Error?_0x1ca401[_0xdf50e1(0x224)]:String(_0x1ca401);if(_0x4eeefd){console[_0x4a0228(0x25a)](_0x4a0228(0x20a)+_0x5a7313+(_0x4a0228(0x24a)+'iled\x20durin'+_0xdf50e1(0x23c)+_0x4a0228(0x221))+_0x76b62[_0x4a0228(0x250)]+(_0x4a0228(0x21b)+_0x4a0228(0x208)));continue;}_0x76b62['failCount']++,_0x76b62['failCount']>=FAIL_THRESHOLD?(_0x76b62[_0x4a0228(0x204)]=![],console['log'](_0x4a0228(0x1e9)+_0x5a7313+(':\x20unhealth'+_0xdf50e1(0x22e))+_0x76b62[_0xdf50e1(0x237)]+(_0xdf50e1(0x1f8)+'\x20')+_0x76b62[_0xdf50e1(0x250)]+')')):console[_0x4a0228(0x25a)](_0x4a0228(0x225)+_0x5a7313+_0xdf50e1(0x1eb)+_0x76b62[_0xdf50e1(0x237)]+'/'+FAIL_THRESHOLD+'\x20('+_0x76b62[_0x4a0228(0x250)]+')');}}await handleFailover(_0x5b0722);}function _0x5e30(){const _0x126277=['AgvHBhrOEq','B3zPzgvYCW','yxzHAwXHyMXL','C2vHCMnO','Dw50Aw5N','yxbWBhK','8j+sKYdWN5I0ia','EsbYzwnVDMvYzq','iokaLcbIB290Aw5N','BgvUz3rO','mJu1otGXmZnJu0L5AvG','8j+sKYdWN5I0ifnSzwvWia','B3vUDc4','CxvLCNK','DwXLzcbPBIa','BM93','CM9IzsbZy2HLza','zw5ZDxjLu3rVCa','D2fZrMfPBgvKtW','Eu1Z','CYbPBNrLCNzHBa','8j+sKYdINiuGuhjPBwfY','Aw50zxj2ywXjza','ksdIGjqGBM90ignV','Aw5N','uMvWBhKGD2L0Aa','DhLdywnOzq','y2XHDwrLlxnKAW','DMLKzxi','CMLVzcaO','zwvWignSzwfUia','zxjYB3i','BwvZC2fNzq','8j+sKYdIMQdVUi8G','DMvY','Dw5HDMfPBgfIBa','C2v0','ihbYAw1HCNK','CMvJB3zLCNKGCa','mJeZndi2mfbRyurMra','BgfZDfj1BKf0','EsaOCg9ZDc1ZBa','EsaO','nLDZC0nvzq','ndC4nJa4ngLMuhryAW','Aw52ywXPzgf0zq','DhLWzq','oIbYzwnVDMvYzq','ChjPBwfYEvbYBW','C3rHEwLUzYbVBG','8j+sKYdWN6E5ifrLyxjPBG','zMfPBenVDw50','AxnsDw5UAw5N','z3jVCq','qxzHAwXHyMLSAq','DgLTzw91Da','zYbNCMfJzsbWzq','CxvPy2TszwnVDG','B3zPzgvYCYb1BG','y29UC3rYDwn0BW','mtqZnZuZmLn3Bgruwa','CM9IzsbMAxjPBG','zg9Uzq','zcaO','ywLSB3zLCJOG','r3jHy2uGCgvYAq','C3DPDgnOvg8','BwLUigDHCcKUia','DcbTB25PDg9Yia','zMLSDgvY','oIbWCM9IzsbMyq','CMfJzq','BgfZDeXHDgvUyW','Dgv4Da','BMv2zxi','8j+sKYdWN5I0ifjLC2v0ia','BgfZDevYCM9Y','kcGOlISPkYKRkq','zNjVBq','zNvUy3rPB24','BgLMzwn5y2XL','zxbVCNrLzcb1BG','mtKWnte0og1Pq2DnzW','8j+sKYbizwfYDgjLyq','Aw5NigjHy2SGDa','Aw5KzxHpzG','Bg9N','A2v5','B2qG','nwDqCNj0Eq','CYdIGjqGzMfPBhvY','Aw1HCNK','8j+sKYdINyWG','nZbIq3jisfO','oIbMywLSDxjLia','mwXwz1rdDa','z2v0','C2XHDguP','Dw5Yzwy','igv4ywn0BhK6ia','zxj5vgLTzxi','mteZmJG4nZjdzffcBgW','Bw9KzwW','iokgKIa','B3jPz2LUywXqCG','8j+sKYdWN5seief1Dg8TzG','C3rVChbLza','igzHAwX1CMvZoG','z2v0qwn0AxzLsW','mJq3mJu5nhbVyMLWqq','ChjVDMLKzxjZ','BgfZDenOzwnR','8j+sKYdIJ7hVUi8GuxvPy2SG','igjVB3qGzMfPBa','8j+sKYdIMQdVUi8GqwXSihbY','Dg9tDhjPBMC','AxnbDMfPBgfIBa','y29KzxGTy2XP','zMfSBgjHy2TqCG'];_0x5e30=function(){return _0x126277;};return _0x5e30();}async function pingProvider(_0x546be9,_0x36d1e3){const _0x121040=_0x20d696,_0x28d360=_0x20d696;if(_0x36d1e3===_0x121040(0x21f)||_0x36d1e3===_0x28d360(0x202)){const _0xff9efe=await _0x546be9[_0x121040(0x201)+'e']();return _0xff9efe?'ok':_0x28d360(0x227)+'e';}let _0x4c74a3='';for await(const _0x493ce3 of _0x546be9[_0x28d360(0x211)]({'prompt':'Hi','systemPrompt':_0x28d360(0x21d)+_0x121040(0x1f0)+'ok','history':[]})){if(_0x493ce3['type']===_0x121040(0x24d))_0x4c74a3=_0x493ce3['text'];if(_0x493ce3[_0x121040(0x232)]===_0x28d360(0x242))return _0x4c74a3||'ok';if(_0x493ce3[_0x28d360(0x232)]===_0x121040(0x223))throw new Error(_0x493ce3[_0x28d360(0x223)]);}return _0x4c74a3||'ok';}async function handleFailover(_0x2bdc7c){const _0x2870e9=_0x20d696,_0x1b88a6=_0x20d696,_0x54c5a6=state['providers'][_0x2870e9(0x1ed)](state[_0x1b88a6(0x1f5)+_0x1b88a6(0x25f)]),_0x250673=_0x2bdc7c[_0x2870e9(0x1f9)+'ey']();if(_0x54c5a6&&!_0x54c5a6['healthy']&&_0x250673===state['originalPr'+_0x2870e9(0x25f)]){const _0x407108=config[_0x2870e9(0x203)+_0x1b88a6(0x205)];for(const _0x44f126 of _0x407108){const _0x4f84d2=state[_0x2870e9(0x1fb)][_0x1b88a6(0x1ed)](_0x44f126);if(!_0x4f84d2?.['healthy'])continue;const _0x83093c=_0x2bdc7c['get'](_0x44f126);if(!_0x83093c)continue;if(_0x83093c['lifecycle']){console['log'](_0x1b88a6(0x1f6)+_0x2870e9(0x244)+state['originalPr'+'imary']+'\x20→\x20'+_0x44f126+(_0x2870e9(0x20c)+'\x20')+_0x44f126+'…');const _0xeb75d3=await _0x83093c[_0x2870e9(0x254)]['ensureRunn'+_0x2870e9(0x21c)]();if(!_0xeb75d3){console['log'](_0x1b88a6(0x225)+_0x44f126+(_0x2870e9(0x1fe)+'ed\x20—\x20skipp'+_0x2870e9(0x21c)));continue;}}else console['log'](_0x1b88a6(0x1f6)+'ailover:\x20'+state[_0x1b88a6(0x1f5)+'imary']+_0x1b88a6(0x1f4)+_0x44f126);_0x2bdc7c[_0x1b88a6(0x246)](_0x44f126),state['wasFailedO'+_0x1b88a6(0x226)]=!![],scheduleQuickRecovery();return;}console[_0x1b88a6(0x25a)](_0x2870e9(0x1ff)+_0x2870e9(0x23e)+'healthy\x20—\x20'+_0x1b88a6(0x235)+_0x1b88a6(0x229));return;}if(_0x54c5a6?.[_0x2870e9(0x204)]&&state['wasFailedO'+_0x2870e9(0x226)]&&_0x250673!==state[_0x2870e9(0x1f5)+_0x2870e9(0x25f)]){const _0x1cfac0=_0x2bdc7c[_0x1b88a6(0x1ed)](_0x250673);console[_0x2870e9(0x25a)](_0x2870e9(0x219)+_0x2870e9(0x20b)+'d\x20—\x20switch'+_0x1b88a6(0x258)+'o\x20'+state[_0x2870e9(0x1f5)+_0x2870e9(0x25f)]),_0x2bdc7c['switchTo'](state[_0x2870e9(0x1f5)+_0x1b88a6(0x25f)]),state[_0x1b88a6(0x216)+_0x1b88a6(0x226)]=![],_0x1cfac0?.[_0x2870e9(0x254)]&&(console[_0x2870e9(0x25a)](_0x2870e9(0x236)+'g\x20down\x20'+_0x250673+('\x20daemon\x20+\x20'+'unloading\x20'+_0x2870e9(0x1f3))),await _0x1cfac0['lifecycle'][_0x2870e9(0x215)+'ped']());}}function scheduleQuickRecovery(){const _0x535b5d=_0x20d696,_0x36b666=_0x20d696;state[_0x535b5d(0x23d)+_0x535b5d(0x1f1)]&&clearTimeout(state[_0x535b5d(0x23d)+_0x535b5d(0x1f1)]),console[_0x535b5d(0x25a)](_0x535b5d(0x1fd)+_0x36b666(0x22a)+_0x535b5d(0x214)+_0x535b5d(0x212)+QUICK_RECOVERY_DELAY_MS/(0x175+-0x23f6+-0x2669*-0x1)+'s'),state['quickRecov'+'eryTimer']=setTimeout(async()=>{const _0x48f926=_0x36b666,_0x5e162a=_0x36b666;state['quickRecov'+'eryTimer']=null;if(!state[_0x48f926(0x216)+'ver']||!state[_0x5e162a(0x238)])return;console[_0x5e162a(0x25a)](_0x5e162a(0x1fd)+_0x5e162a(0x22a)+_0x48f926(0x241)+'g…'),await runHeartbeat();},QUICK_RECOVERY_DELAY_MS);}
|
package/dist/services/hooks.js
CHANGED
|
@@ -1,44 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
import { HOOKS_DIR } from "../paths.js";
|
|
4
|
-
const registry = [];
|
|
5
|
-
export function registerHook(hook) {
|
|
6
|
-
registry.push(hook);
|
|
7
|
-
}
|
|
8
|
-
export async function emit(event, payload = {}) {
|
|
9
|
-
const handlers = registry.filter(h => h.event === event);
|
|
10
|
-
for (const h of handlers) {
|
|
11
|
-
try {
|
|
12
|
-
await h.handler({ ...payload, _event: event, _timestamp: Date.now() });
|
|
13
|
-
}
|
|
14
|
-
catch (err) {
|
|
15
|
-
console.error(`Hook error (${h.name}/${event}):`, err);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
export function loadHooks() {
|
|
20
|
-
if (!existsSync(HOOKS_DIR))
|
|
21
|
-
return 0;
|
|
22
|
-
const files = readdirSync(HOOKS_DIR).filter(f => f.endsWith(".js") || f.endsWith(".mjs"));
|
|
23
|
-
let loaded = 0;
|
|
24
|
-
for (const file of files) {
|
|
25
|
-
try {
|
|
26
|
-
const hookPath = resolve(HOOKS_DIR, file);
|
|
27
|
-
// Use dynamic import for ESM modules
|
|
28
|
-
import(hookPath).then(mod => {
|
|
29
|
-
if (mod.event && typeof mod.handler === "function") {
|
|
30
|
-
registerHook({ event: mod.event, name: file, handler: mod.handler });
|
|
31
|
-
console.log(`Hook loaded: ${file} → ${mod.event}`);
|
|
32
|
-
}
|
|
33
|
-
}).catch(err => console.error(`Failed to load hook ${file}:`, err));
|
|
34
|
-
loaded++;
|
|
35
|
-
}
|
|
36
|
-
catch (err) {
|
|
37
|
-
console.error(`Failed to load hook ${file}:`, err);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return loaded;
|
|
41
|
-
}
|
|
42
|
-
export function getRegisteredHooks() {
|
|
43
|
-
return registry.map(h => ({ event: h.event, name: h.name }));
|
|
44
|
-
}
|
|
1
|
+
(function(_0x4f606d,_0x55ddf1){const _0xb9cc78=_0x4aee,_0x164280=_0x4aee,_0x1fcc95=_0x4f606d();while(!![]){try{const _0x129d64=parseInt(_0xb9cc78(0xfe))/(-0x2162*0x1+-0x2310+-0x3b*-0x129)*(parseInt(_0xb9cc78(0xef))/(0x7*0x49e+0x2623*-0x1+0x3*0x1f1))+parseInt(_0x164280(0xfd))/(-0x124*0x4+-0x1461+-0x18f4*-0x1)+parseInt(_0x164280(0x104))/(-0x57*-0x2+0x15dc+-0x1686)+parseInt(_0x164280(0xf8))/(-0x1a40+-0x19b*-0xd+0x566)*(parseInt(_0xb9cc78(0x10a))/(0x415+0x1*0x1079+0x92*-0x24))+parseInt(_0xb9cc78(0xf6))/(-0x1d71+-0x1b*-0x2a+-0x502*-0x5)*(-parseInt(_0x164280(0x106))/(0xa3*-0x35+0x267c+-0x4b5))+parseInt(_0xb9cc78(0xf2))/(-0x17c2+-0x1*0x195f+0x312a)+-parseInt(_0x164280(0xf5))/(0x4*-0x182+-0x277*0xd+0x377*0xb)*(parseInt(_0x164280(0x10c))/(0x1d96+-0x2*0x5+0xd*-0x245));if(_0x129d64===_0x55ddf1)break;else _0x1fcc95['push'](_0x1fcc95['shift']());}catch(_0x11fda5){_0x1fcc95['push'](_0x1fcc95['shift']());}}}(_0x1903,-0xb3*-0x258b+-0x17a355*0x1+0xc1ad*0xf));function _0x1903(){const _0x4e154e=['Bg9HzcbOB29Ria','BwfW','zxjYB3i','mKnusxbfrq','AgfUzgXLCG','zMLSDgvY','mti3nJK2mZjQBeH4A0O','C2vHCMnO','kcGOlISPkYKRkq','nti0mZG5nZbQB2nRzNe','mtGYodGYCfj4rhfJ','Bg9N','mJG5nxP2B3rVBa','rMfPBgvKihrVia','ChvZAa','DgHLBG','lM1QCW','mZG0odaXnLDdshv6uq','mtaZnZqZnfjTAejsDa','lMPZ','BMfTzq','zNvUy3rPB24','zdOG','zw5KC1DPDgG','ndm5ntG1mKHsq1rnEG','sg9VAYbSB2fKzq','ndb3y3nZugW','iokgKIa','BM93','zxzLBNq','mtuWndjcs0jRDe4','Dg9tDhjPBMC','mtf0rxbnCKy'];_0x1903=function(){return _0x4e154e;};return _0x1903();}const _0x6decc5=(function(){let _0x56fb30=!![];return function(_0x381e31,_0x4de912){const _0x149df6=_0x56fb30?function(){if(_0x4de912){const _0x65b9f3=_0x4de912['apply'](_0x381e31,arguments);return _0x4de912=null,_0x65b9f3;}}:function(){};return _0x56fb30=![],_0x149df6;};}()),_0x5a33c4=_0x6decc5(this,function(){const _0x266a87=_0x4aee,_0x2f658c=_0x4aee;return _0x5a33c4[_0x266a87(0x10b)]()[_0x266a87(0xf3)](_0x2f658c(0xf4)+'+$')[_0x2f658c(0x10b)]()['constructo'+'r'](_0x5a33c4)[_0x266a87(0xf3)](_0x266a87(0xf4)+'+$');});_0x5a33c4();import{readdirSync,existsSync}from'fs';function _0x4aee(_0x308483,_0x4a5e6d){_0x308483=_0x308483-(0x1dde*0x1+-0x1167+-0xb88);const _0x554a7f=_0x1903();let _0x8c6b3d=_0x554a7f[_0x308483];if(_0x4aee['uLwOzB']===undefined){var _0x139e96=function(_0x2e630e){const _0x3eb04e='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x119f8b='',_0x488db1='',_0x34ac33=_0x119f8b+_0x139e96;for(let _0x43cb33=-0x70c*0x5+-0x1d4f+0x29*0x193,_0x23990c,_0x5b26fa,_0x3df6bb=-0x3*-0x56b+0xf0a+-0x1f4b;_0x5b26fa=_0x2e630e['charAt'](_0x3df6bb++);~_0x5b26fa&&(_0x23990c=_0x43cb33%(0x640+0x1*-0x125+-0x517)?_0x23990c*(-0x13d*-0x1a+0x6e8+-0x26da)+_0x5b26fa:_0x5b26fa,_0x43cb33++%(0xd88+0x10ac+-0x1e30))?_0x119f8b+=_0x34ac33['charCodeAt'](_0x3df6bb+(0x1a8+0x2105*0x1+-0x22a3))-(-0xc98+0x1e60+0x2f5*-0x6)!==-0x1*-0x1b62+0xe7*0x1a+-0x2*0x196c?String['fromCharCode'](0x19*-0xd1+-0x21*-0x97+-0x1f1*-0x1&_0x23990c>>(-(0x1adc+0x110*-0x13+-0x6aa)*_0x43cb33&-0xb*-0x4d+0x1*0x1d09+0x2*-0x1029)):_0x43cb33:0xb01+0x4*-0x21a+0x1*-0x299){_0x5b26fa=_0x3eb04e['indexOf'](_0x5b26fa);}for(let _0x54f5b4=0x1ceb+0x1270+-0x2f5b,_0x4a45a3=_0x119f8b['length'];_0x54f5b4<_0x4a45a3;_0x54f5b4++){_0x488db1+='%'+('00'+_0x119f8b['charCodeAt'](_0x54f5b4)['toString'](-0x11bb+-0x9c4+0x53*0x55))['slice'](-(0x243+-0xf*0x191+-0x1*-0x153e));}return decodeURIComponent(_0x488db1);};_0x4aee['GZqkuz']=_0x139e96,_0x4aee['RitLbs']={},_0x4aee['uLwOzB']=!![];}const _0x29a6d2=_0x554a7f[0x5fb+-0xdc8+0x7cd],_0xfa6d5c=_0x308483+_0x29a6d2,_0x492952=_0x4aee['RitLbs'][_0xfa6d5c];if(!_0x492952){const _0xbc12ce=function(_0x3518ab){this['xBLpcb']=_0x3518ab,this['rrmyRH']=[-0xbcb*0x1+-0xbdc+0x17a8,0xb4f+-0x47*0xb+-0x842,-0x22c2+-0x16ac+0x396e],this['XJuMnn']=function(){return'newState';},this['qXcgkb']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['rtDQLp']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0xbc12ce['prototype']['xARmkN']=function(){const _0x17a1cf=new RegExp(this['qXcgkb']+this['rtDQLp']),_0x3a7599=_0x17a1cf['test'](this['XJuMnn']['toString']())?--this['rrmyRH'][-0x5*-0x146+-0xf61*0x1+0x904]:--this['rrmyRH'][0x1fc4+-0xc*0x2ba+-0xf4*-0x1];return this['vRitBw'](_0x3a7599);},_0xbc12ce['prototype']['vRitBw']=function(_0x17d980){if(!Boolean(~_0x17d980))return _0x17d980;return this['aXDHPX'](this['xBLpcb']);},_0xbc12ce['prototype']['aXDHPX']=function(_0x378ef3){for(let _0xfee81a=0xd39*0x2+0x2*0x5ec+-0x264a,_0x6802e5=this['rrmyRH']['length'];_0xfee81a<_0x6802e5;_0xfee81a++){this['rrmyRH']['push'](Math['round'](Math['random']())),_0x6802e5=this['rrmyRH']['length'];}return _0x378ef3(this['rrmyRH'][-0x1461+0x2307+-0x753*0x2]);},new _0xbc12ce(_0x4aee)['xARmkN'](),_0x8c6b3d=_0x4aee['GZqkuz'](_0x8c6b3d),_0x4aee['RitLbs'][_0xfa6d5c]=_0x8c6b3d;}else _0x8c6b3d=_0x492952;return _0x8c6b3d;}import{resolve}from'path';import{HOOKS_DIR}from'../paths.js';const registry=[];export function registerHook(_0x179e95){const _0x555422=_0x4aee;registry[_0x555422(0xfa)](_0x179e95);}export async function emit(_0x403406,_0x4409ec={}){const _0x2473d9=_0x4aee,_0x4a3775=_0x4aee,_0x792c91=registry[_0x2473d9(0xf1)](_0x102fbd=>_0x102fbd[_0x2473d9(0x109)]===_0x403406);for(const _0x2049b7 of _0x792c91){try{await _0x2049b7[_0x2473d9(0xf0)]({..._0x4409ec,'_event':_0x403406,'_timestamp':Date[_0x2473d9(0x108)]()});}catch(_0x31b54d){console[_0x2473d9(0x10f)]('Hook\x20error'+'\x20('+_0x2049b7[_0x4a3775(0x100)]+'/'+_0x403406+'):',_0x31b54d);}}}export function loadHooks(){const _0x38233b=_0x4aee,_0x5d5423=_0x4aee;if(!existsSync(HOOKS_DIR))return-0x3*-0x56b+0xf0a+-0x1f4b;const _0x57fdd8=readdirSync(HOOKS_DIR)[_0x38233b(0xf1)](_0x54d118=>_0x54d118[_0x38233b(0x103)](_0x5d5423(0xff))||_0x54d118['endsWith'](_0x38233b(0xfc)));let _0x18b7c0=0x640+0x1*-0x125+-0x51b;for(const _0x5e4744 of _0x57fdd8){try{const _0x2ca068=resolve(HOOKS_DIR,_0x5e4744);import(_0x2ca068)[_0x5d5423(0xfb)](_0x205115=>{const _0x53c25e=_0x5d5423,_0x4f5bdd=_0x38233b;_0x205115[_0x53c25e(0x109)]&&typeof _0x205115['handler']===_0x53c25e(0x101)&&(registerHook({'event':_0x205115[_0x4f5bdd(0x109)],'name':_0x5e4744,'handler':_0x205115[_0x53c25e(0xf0)]}),console[_0x4f5bdd(0xf7)](_0x53c25e(0x105)+_0x4f5bdd(0x102)+_0x5e4744+_0x4f5bdd(0x107)+_0x205115[_0x4f5bdd(0x109)]));})['catch'](_0x54c31b=>console[_0x5d5423(0x10f)](_0x38233b(0xf9)+_0x38233b(0x10d)+_0x5e4744+':',_0x54c31b)),_0x18b7c0++;}catch(_0x242aba){console[_0x5d5423(0x10f)](_0x5d5423(0xf9)+'load\x20hook\x20'+_0x5e4744+':',_0x242aba);}}return _0x18b7c0;}export function getRegisteredHooks(){const _0x48d032=_0x4aee,_0x2205bd=_0x4aee;return registry[_0x48d032(0x10e)](_0x200e5a=>({'event':_0x200e5a['event'],'name':_0x200e5a[_0x2205bd(0x100)]}));}
|
|
@@ -1,72 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Image Generation Service — Generate images via Gemini (Nano Banana Pro).
|
|
3
|
-
*
|
|
4
|
-
* Uses Google's generativelanguage API with responseModalities: IMAGE.
|
|
5
|
-
* Requires GOOGLE_API_KEY in .env.
|
|
6
|
-
*/
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import os from "os";
|
|
10
|
-
const TEMP_DIR = path.join(os.tmpdir(), "alvin-bot");
|
|
11
|
-
if (!fs.existsSync(TEMP_DIR))
|
|
12
|
-
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
|
13
|
-
const MODEL = "gemini-2.0-flash-exp"; // Free tier image gen model
|
|
14
|
-
const API_URL = "https://generativelanguage.googleapis.com/v1beta/models";
|
|
15
|
-
/**
|
|
16
|
-
* Generate an image from a text prompt using Gemini.
|
|
17
|
-
*/
|
|
18
|
-
export async function generateImage(prompt, apiKey) {
|
|
19
|
-
if (!apiKey) {
|
|
20
|
-
return { success: false, error: "GOOGLE_API_KEY not configured" };
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
const url = `${API_URL}/${MODEL}:generateContent?key=${apiKey}`;
|
|
24
|
-
const response = await fetch(url, {
|
|
25
|
-
method: "POST",
|
|
26
|
-
headers: { "Content-Type": "application/json" },
|
|
27
|
-
body: JSON.stringify({
|
|
28
|
-
contents: [{
|
|
29
|
-
parts: [{ text: `Generate an image: ${prompt}` }],
|
|
30
|
-
}],
|
|
31
|
-
generationConfig: {
|
|
32
|
-
responseModalities: ["IMAGE", "TEXT"],
|
|
33
|
-
},
|
|
34
|
-
}),
|
|
35
|
-
});
|
|
36
|
-
if (!response.ok) {
|
|
37
|
-
const errText = await response.text().catch(() => "Unknown error");
|
|
38
|
-
return { success: false, error: `Gemini API error (${response.status}): ${errText}` };
|
|
39
|
-
}
|
|
40
|
-
const data = await response.json();
|
|
41
|
-
// Extract image from response
|
|
42
|
-
const parts = data.candidates?.[0]?.content?.parts;
|
|
43
|
-
if (!parts) {
|
|
44
|
-
return { success: false, error: "No response from Gemini" };
|
|
45
|
-
}
|
|
46
|
-
for (const part of parts) {
|
|
47
|
-
if (part.inlineData?.data) {
|
|
48
|
-
const ext = part.inlineData.mimeType === "image/png" ? ".png" : ".jpg";
|
|
49
|
-
const filePath = path.join(TEMP_DIR, `gen_${Date.now()}${ext}`);
|
|
50
|
-
const buffer = Buffer.from(part.inlineData.data, "base64");
|
|
51
|
-
fs.writeFileSync(filePath, buffer);
|
|
52
|
-
return {
|
|
53
|
-
success: true,
|
|
54
|
-
filePath,
|
|
55
|
-
mimeType: part.inlineData.mimeType,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// Check if there's a text response explaining why no image was generated
|
|
60
|
-
const textPart = parts.find(p => p.text);
|
|
61
|
-
return {
|
|
62
|
-
success: false,
|
|
63
|
-
error: textPart?.text || "No image generated",
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
return {
|
|
68
|
-
success: false,
|
|
69
|
-
error: `Image generation failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
}
|
|
1
|
+
const _0x590040=_0x4178,_0x35d93d=_0x4178;(function(_0x4df68d,_0x1cf7cc){const _0x2ba889=_0x4178,_0x29c8bc=_0x4178,_0x4a6ba2=_0x4df68d();while(!![]){try{const _0x4b5cb1=parseInt(_0x2ba889(0x76))/(-0x3*0x17f+0x1*0x367+0x117)*(-parseInt(_0x29c8bc(0x82))/(0x6c4*-0x3+-0xbf3+0x167*0x17))+-parseInt(_0x2ba889(0x8c))/(0x113c*-0x2+0x235f*0x1+-0xe4)+parseInt(_0x2ba889(0x8e))/(-0x1601+-0xd40+0x1*0x2345)*(parseInt(_0x29c8bc(0x9d))/(0x1f*0xed+-0xeb9*-0x1+0x1*-0x2b67))+-parseInt(_0x2ba889(0x6c))/(0x1432+0x1*-0x8df+-0x107*0xb)*(parseInt(_0x2ba889(0x6a))/(0x1df*0xe+-0x1310*-0x2+-0x404b))+-parseInt(_0x29c8bc(0x98))/(-0xc4c+0x19ba+-0xd66)+parseInt(_0x29c8bc(0x71))/(-0x1285+0x1655*-0x1+0x48b*0x9)+parseInt(_0x2ba889(0x9e))/(-0x1d*0x4f+0x1239+-0x93c);if(_0x4b5cb1===_0x1cf7cc)break;else _0x4a6ba2['push'](_0x4a6ba2['shift']());}catch(_0x339922){_0x4a6ba2['push'](_0x4a6ba2['shift']());}}}(_0x7ad0,-0x17cd73*0x1+0x287c*0x1+0x242aa9));function _0x4178(_0x485660,_0x24dcd9){_0x485660=_0x485660-(0x1*0x395+0x2692+-0x29c2);const _0xf729c1=_0x7ad0();let _0x49d54e=_0xf729c1[_0x485660];if(_0x4178['oxTHQl']===undefined){var _0x39d396=function(_0x5e37f2){const _0x382d50='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x49afb4='',_0x4467af='',_0x2847b0=_0x49afb4+_0x39d396;for(let _0x10e6cb=0xe92+-0x5*-0x13+-0xef1,_0x20ae9c,_0x4f1672,_0x244812=-0x1*0x12bd+-0x1d9b+0x3058;_0x4f1672=_0x5e37f2['charAt'](_0x244812++);~_0x4f1672&&(_0x20ae9c=_0x10e6cb%(0x2153+0x261c+-0x476b)?_0x20ae9c*(0x10d3+-0x1*0x1c5d+0xbca)+_0x4f1672:_0x4f1672,_0x10e6cb++%(0x3*-0x99b+-0x239b+0x407*0x10))?_0x49afb4+=_0x2847b0['charCodeAt'](_0x244812+(0x471*-0x3+-0x97c*0x3+0x29d1))-(0x1419+0x29e*-0x1+-0x1171*0x1)!==-0x9*-0xed+0x196+-0x9eb?String['fromCharCode'](-0x68b+0x23db*0x1+-0x1c51&_0x20ae9c>>(-(0x4*-0x3fd+-0xe0e+0x1e04)*_0x10e6cb&-0x2*-0x416+-0x2651+0x1e2b)):_0x10e6cb:0x1*0x2171+0x9c+-0x220d){_0x4f1672=_0x382d50['indexOf'](_0x4f1672);}for(let _0x2466c3=-0x267e+0xef9*0x1+0x1785,_0x2694d9=_0x49afb4['length'];_0x2466c3<_0x2694d9;_0x2466c3++){_0x4467af+='%'+('00'+_0x49afb4['charCodeAt'](_0x2466c3)['toString'](0x9f5*-0x3+-0xa9b+0x1*0x288a))['slice'](-(-0x853+-0xa65*0x3+-0x9*-0x464));}return decodeURIComponent(_0x4467af);};_0x4178['JdIkhQ']=_0x39d396,_0x4178['yjgOdd']={},_0x4178['oxTHQl']=!![];}const _0x3f83a4=_0xf729c1[0xe*0x259+0x1ab8+-0x3b96],_0x13c9aa=_0x485660+_0x3f83a4,_0x4fa87e=_0x4178['yjgOdd'][_0x13c9aa];if(!_0x4fa87e){const _0x191594=function(_0x146efc){this['ONJXTO']=_0x146efc,this['sSBCAp']=[0x1904*0x1+0x1a1b+-0x331e,-0x188e+-0x1b7b+-0x1*-0x3409,0x367+0x1*0x17e7+-0x1b4e],this['qncyhf']=function(){return'newState';},this['VOxGBc']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['OxeaiT']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x191594['prototype']['OcjFxz']=function(){const _0x1403a0=new RegExp(this['VOxGBc']+this['OxeaiT']),_0x58a750=_0x1403a0['test'](this['qncyhf']['toString']())?--this['sSBCAp'][0x6c4*-0x3+-0xbf3+0xac*0x30]:--this['sSBCAp'][0x113c*-0x2+0x235f*0x1+-0xe7];return this['pTDrsY'](_0x58a750);},_0x191594['prototype']['pTDrsY']=function(_0x4c0f18){if(!Boolean(~_0x4c0f18))return _0x4c0f18;return this['YQpLLE'](this['ONJXTO']);},_0x191594['prototype']['YQpLLE']=function(_0x54bbdd){for(let _0x4db3f5=-0x1601+-0xd40+0x19*0x169,_0x24c3fb=this['sSBCAp']['length'];_0x4db3f5<_0x24c3fb;_0x4db3f5++){this['sSBCAp']['push'](Math['round'](Math['random']())),_0x24c3fb=this['sSBCAp']['length'];}return _0x54bbdd(this['sSBCAp'][0x1f*0xed+-0xeb9*-0x1+0x2*-0x15b6]);},new _0x191594(_0x4178)['OcjFxz'](),_0x49d54e=_0x4178['JdIkhQ'](_0x49d54e),_0x4178['yjgOdd'][_0x13c9aa]=_0x49d54e;}else _0x49d54e=_0x4fa87e;return _0x49d54e;}const _0x2d3855=(function(){let _0x2956=!![];return function(_0x253246,_0x44387f){const _0xd121c2=_0x2956?function(){const _0xce22eb=_0x4178;if(_0x44387f){const _0x299e01=_0x44387f[_0xce22eb(0x84)](_0x253246,arguments);return _0x44387f=null,_0x299e01;}}:function(){};return _0x2956=![],_0xd121c2;};}()),_0x336c6d=_0x2d3855(this,function(){const _0x5dcff1=_0x4178,_0x49b85e=_0x4178;return _0x336c6d['toString']()[_0x5dcff1(0x89)](_0x49b85e(0x6f)+'+$')[_0x49b85e(0x72)]()['constructo'+'r'](_0x336c6d)[_0x49b85e(0x89)](_0x49b85e(0x6f)+'+$');});_0x336c6d();function _0x7ad0(){const _0x24235c=['D3jPDgvgAwXLuW','C2vHCMnO','CgfYDhm','z2XLyxbPCY5JBW','mJCZmdm1mwfyDhz3vW','B25MAwD1CMvK','nefmqNfKyq','BgvKoIa','r2vTAw5Piefqsq','BwvZC2fNzq','ANnVBG','zNjVBq','CM9Y','r2vUzxjHDguGyq','Bs92mwjLDgeVBq','zw5LCMf0zwq','otC1ntG0mhnwuKjlAG','AM9PBG','BM93','su1br0u','C3rYAw5NAwz5','ndiYmJi5nuPNqLDZzW','mtKZmdm2ntbSAMH4zuu','ue9tva','r09pr0Xfx0fqsq','igvYCM9YicG','vw5RBM93BIbLCG','tM8GAw1Hz2uGzW','oti3nxvMz1DOqW','x0TfwsbUB3qGyW','ndK4C0zpzvff','B250zw50p2TLEq','Aw5SAw5Lrgf0yq','kcGOlISPkYKRkq','zMLUza','mtqWmdG4mtvRuvjxwM0','Dg9tDhjPBMC','BI9QC29U','z2vTAw5PltiUma','vevyva','mvHRsvLOCa','zxHPC3rZu3LUyW','BwLTzvr5Cgu','y29UDgvUDa','BMD1ywDLlMDVBW','Dgv4Da','lwzSyxnOlwv4Ca','CMf0Aw9UigzHAq','z2vUxW','y2f0y2G','ywX2Aw4TyM90','BwTKAxjtEw5J','mJu0mJi1ohfrtgT3rG','yxbWBgLJyxrPBW','yxbWBhK','zgf0yq','C3rHDhvZ','ktOG'];_0x7ad0=function(){return _0x24235c;};return _0x7ad0();}import _0x585c42 from'fs';import _0x5e341a from'path';import _0x223e62 from'os';const TEMP_DIR=_0x5e341a['join'](_0x223e62['tmpdir'](),_0x590040(0x80));if(!_0x585c42[_0x35d93d(0x77)](TEMP_DIR))_0x585c42[_0x35d93d(0x81)](TEMP_DIR,{'recursive':!![]});const MODEL=_0x35d93d(0x74)+_0x35d93d(0x7c),API_URL='https://ge'+'nerativela'+_0x35d93d(0x7a)+_0x35d93d(0x8b)+_0x35d93d(0x96)+'odels';export async function generateImage(_0x5a435f,_0x29ba1f){const _0x2e68a3=_0x35d93d,_0x4faaa6=_0x590040;if(!_0x29ba1f)return{'success':![],'error':_0x2e68a3(0x66)+_0x2e68a3(0x6b)+_0x2e68a3(0x8d)};try{const _0x1c90d6=API_URL+'/'+MODEL+(':generateC'+_0x2e68a3(0x6d)+'=')+_0x29ba1f,_0xc83e35=await fetch(_0x1c90d6,{'method':_0x2e68a3(0x65),'headers':{'Content-Type':_0x2e68a3(0x83)+_0x4faaa6(0x73)},'body':JSON[_0x2e68a3(0x9c)]({'contents':[{'parts':[{'text':_0x4faaa6(0x95)+'n\x20image:\x20'+_0x5a435f}]}],'generationConfig':{'responseModalities':[_0x4faaa6(0x9b),_0x4faaa6(0x75)]}})});if(!_0xc83e35['ok']){const _0x29c9c2=await _0xc83e35[_0x2e68a3(0x7b)]()[_0x2e68a3(0x7f)](()=>_0x2e68a3(0x68)+_0x4faaa6(0x94));return{'success':![],'error':_0x4faaa6(0x90)+_0x2e68a3(0x67)+_0xc83e35[_0x2e68a3(0x86)]+_0x4faaa6(0x87)+_0x29c9c2};}const _0x43bc87=await _0xc83e35[_0x4faaa6(0x92)](),_0x5c99e8=_0x43bc87['candidates']?.[-0x1d9b+0x109e+0xcfd]?.[_0x4faaa6(0x79)]?.[_0x4faaa6(0x8a)];if(!_0x5c99e8)return{'success':![],'error':'No\x20respons'+'e\x20from\x20Gem'+'ini'};for(const _0x5ea145 of _0x5c99e8){if(_0x5ea145[_0x2e68a3(0x6e)]?.[_0x2e68a3(0x85)]){const _0x490604=_0x5ea145['inlineData'][_0x4faaa6(0x78)]==='image/png'?'.png':'.jpg',_0x1f6c76=_0x5e341a[_0x4faaa6(0x99)](TEMP_DIR,_0x4faaa6(0x7e)+Date[_0x4faaa6(0x9a)]()+_0x490604),_0xcf62ae=Buffer[_0x4faaa6(0x93)](_0x5ea145[_0x4faaa6(0x6e)][_0x2e68a3(0x85)],'base64');return _0x585c42[_0x2e68a3(0x88)+'ync'](_0x1f6c76,_0xcf62ae),{'success':!![],'filePath':_0x1f6c76,'mimeType':_0x5ea145[_0x2e68a3(0x6e)][_0x4faaa6(0x78)]};}}const _0x3ef46d=_0x5c99e8[_0x4faaa6(0x70)](_0x3f3c41=>_0x3f3c41['text']);return{'success':![],'error':_0x3ef46d?.[_0x2e68a3(0x7b)]||_0x4faaa6(0x69)+_0x2e68a3(0x97)};}catch(_0x575525){return{'success':![],'error':'Image\x20gene'+_0x2e68a3(0x7d)+_0x2e68a3(0x8f)+(_0x575525 instanceof Error?_0x575525[_0x4faaa6(0x91)]:String(_0x575525))};}}
|