alvin-bot 5.6.2 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +1 -1
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -130
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -443
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -0
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1831
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,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
|
+
function _0x149a(){const _0xa65493=['oIb1BMHLywX0Aa','z2v0','igrHzw1VBIaRia','DMLKzxi','AxnsDw5UAw5N','C2XHDguP','zwvWignSzwfUia','8j+sKYdIMQdVUi8G','y2XHDwrLlxnKAW','BxmP','EsaOCg9ZDc1ZBa','mtC0mtq4mKT3DevMrG','B3jPz2LUywXqCG','DhLWzq','Bw9KzwW','zxj5vgLTzxi','8j+sKYdWN6E5ifrLyxjPBG','EsbYzwnVDMvYzq','B2qG','zw5ZDxjLuNvUBG','AxnbDMfPBgfIBa','AgvHBhrOEq','ihrVigHLywX0Aa','zw5ZDxjLu3rVCa','DgLTzw91Da','qxzHAwXHyMLSAq','mtu1mdi0muj0rw9eqq','CgvK','zMfSBgjHy2TqCG','zwqG4OcuihnRAxbW','Dgv4Da','BgfZDevYCM9Y','DcbTB25PDg9Yia','iokgKIa','BgfZDfj1BKf0','mZKZndi0y3rjvNjg','y29UC3rYDwn0BW','BwvZC2fNzq','zNjVBq','Aw50zxj2ywXjza','nfr5v0PwzW','BwLUigDHCcKUia','8j+sKYdIJ7hVUi8GuxvPy2SG','oIbWCM9IzsbMyq','yxzHAwXHyMXL','igjVB3qGzMfPBa','C2vHCMnO','Bg9N','igzHAwX1CMvZoG','B3zPzgvYCW','8j+sKYbizwfYDgjLyq','DwXLzcbPBIa','DMfSDwvZ','mJmYmtu3n3HoBxfqDG','8j+sKYdWN5I0ifnSzwvWia','ywLSB3zLCJOG','D2fZrMfPBgvKtW','Aw5NigjHy2SGDa','AgvHBhrOEsdIGjqG','BgLMzwn5y2XL','Dg9tDhjPBMC','ihbYB3zPzgvYCW','Eu1Z','iokaLcbIB290Aw5N','BgfZDeXHDgvUyW','C3rHEwLUzYbVBG','r3jHy2uGCgvYAq','oIbYzwnVDMvYzq','BgfZDenOzwnR','Aw1HCNK','A2v5','AwXLzcbKDxjPBG','CMvJB3zLCNKGCa','CMfJzq','CMLVzcaO','Dw5Yzwy','oIbMywLSDxjLia','mte0mtq1mgTIDMHdqW','8j+sKYdINiuGuhjPBwfY','zYbKB3DUia','kcGOlISPkYKRkq','C2v0','yxbWBhK','CYbPBNrLCNzHBa','uMvWBhKGD2L0Aa','CxvPy2TszwnVDG','Aw5N','Dw5HDMfPBgfIBa','z3jHy2vvBNrPBa','z3jVCq','ChjVDMLKzxjZ','zcaO','8j+sKYdWN5I0ifjLC2v0ia','DhLdywnOzq','ksdIGjqGBM90ignV','igv4ywn0BhK6ia','C3DPDgnOvg8','Aw52ywXPzgf0zq','nJeZnte3nNzAu2PNBa','8j+sKYdWN5seief1Dg8TzG','DMvY','ovHcsxfzqq','zg9Uzq','BM93','zgv0zwn0zwqGka','CM9IzsbZy2HLza','ihbYAw1HCNK','mtqZndqZmgzdCwD1wq','Aw5KzxHpzG','z2v0qwn0AxzLsW','CYdIGjqGzMfPBhvY','8j+sKYdINyWG','zxjYB3i','8j+sKYa','zNvUy3rPB24','CM91BMq','zMfPBenVDw50','BMv2zxi'];_0x149a=function(){return _0xa65493;};return _0x149a();}const _0x151201=_0x458a;(function(_0xc46101,_0x15189b){const _0x79f2e4=_0x458a,_0x569148=_0x458a,_0x112cee=_0xc46101();while(!![]){try{const _0x2252b1=parseInt(_0x79f2e4(0xc7))/(0x5a4+-0x22b0+0x1d0d)+-parseInt(_0x569148(0x10f))/(0x1f01+0x4b2*0x5+0xae5*-0x5)+-parseInt(_0x569148(0xd9))/(0x1*-0xff3+-0x26ad+0x36a3)*(-parseInt(_0x79f2e4(0xcc))/(0x59f*0x1+0x1ee1+0x2*-0x123e))+-parseInt(_0x569148(0xf1))/(0xe7*0xb+0x1*-0x1d3e+-0x5*-0x3de)+-parseInt(_0x569148(0x125))/(-0x109c+0x2*0x22d+-0x189*-0x8)+-parseInt(_0x79f2e4(0xbe))/(-0x1*0xaed+0x16e1+-0xbed)+parseInt(_0x79f2e4(0x106))/(-0x6a8+0xd8b+0x2d*-0x27)*(parseInt(_0x569148(0x109))/(-0xdb+-0x1*0x2b1+-0x395*-0x1));if(_0x2252b1===_0x15189b)break;else _0x112cee['push'](_0x112cee['shift']());}catch(_0x552344){_0x112cee['push'](_0x112cee['shift']());}}}(_0x149a,0x70d63*0x1+-0x84f22+-0x22239*-0x4));const _0x136f32=(function(){let _0x588c6c=!![];return function(_0x2b9127,_0x18ef95){const _0x48247e=_0x588c6c?function(){const _0x368247=_0x458a;if(_0x18ef95){const _0xa73aae=_0x18ef95[_0x368247(0xf6)](_0x2b9127,arguments);return _0x18ef95=null,_0xa73aae;}}:function(){};return _0x588c6c=![],_0x48247e;};}()),_0x5e1705=_0x136f32(this,function(){const _0x1d904a=_0x458a,_0x457bab=_0x458a;return _0x5e1705[_0x1d904a(0xe0)]()[_0x1d904a(0xd2)](_0x457bab(0xf4)+'+$')[_0x457bab(0xe0)]()[_0x1d904a(0xc8)+'r'](_0x5e1705)[_0x1d904a(0xd2)](_0x1d904a(0xf4)+'+$');});_0x5e1705();import{getRegistry}from'../engine.js';function _0x458a(_0x1b3e6d,_0xe69372){_0x1b3e6d=_0x1b3e6d-(0x165d+-0xb3*0x19+-0x42a);const _0x29bcda=_0x149a();let _0x5d7574=_0x29bcda[_0x1b3e6d];if(_0x458a['uNVGct']===undefined){var _0x65165=function(_0x25ce3c){const _0x6ff257='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2de94d='',_0xf8787b='',_0x16ccd9=_0x2de94d+_0x65165;for(let _0x52e698=0x11e8+0x21f1+-0x1*0x33d9,_0x56aea4,_0x3ee40c,_0x4a4abd=-0x9c5+0x9d*-0x2+0xaff;_0x3ee40c=_0x25ce3c['charAt'](_0x4a4abd++);~_0x3ee40c&&(_0x56aea4=_0x52e698%(-0x1712+0x248b+-0xd75)?_0x56aea4*(0x25*0x67+-0x1f4f+-0x42b*-0x4)+_0x3ee40c:_0x3ee40c,_0x52e698++%(0x262e+-0x53*0x7+0x3fd*-0x9))?_0x2de94d+=_0x16ccd9['charCodeAt'](_0x4a4abd+(-0x1dc9+-0x236f+0x4142))-(0x1*0x150d+0x1*0xc71+-0x2174)!==-0x16fc*0x1+0xb08+0x99*0x14?String['fromCharCode'](-0x21a8+-0x1*0x1414+-0x1*-0x36bb&_0x56aea4>>(-(0x173b+0x149d*0x1+-0x2bd6)*_0x52e698&0x3*0x319+0x454*0x3+0x1*-0x1641)):_0x52e698:-0x24aa+-0x10f7*-0x2+-0xaf*-0x4){_0x3ee40c=_0x6ff257['indexOf'](_0x3ee40c);}for(let _0x3e6fac=-0x172*-0xb+0x2*-0x7c1+-0x64,_0x209ac5=_0x2de94d['length'];_0x3e6fac<_0x209ac5;_0x3e6fac++){_0xf8787b+='%'+('00'+_0x2de94d['charCodeAt'](_0x3e6fac)['toString'](-0x14*0x102+0x1373+-0xc5*-0x1))['slice'](-(-0x131b+-0xb60+0x1e7d));}return decodeURIComponent(_0xf8787b);};_0x458a['KKhVGJ']=_0x65165,_0x458a['abvDsQ']={},_0x458a['uNVGct']=!![];}const _0x49bb57=_0x29bcda[-0x1*-0x1c2b+0x2377+-0x3fa2],_0x2c9047=_0x1b3e6d+_0x49bb57,_0x1fe2ce=_0x458a['abvDsQ'][_0x2c9047];if(!_0x1fe2ce){const _0x59e710=function(_0x3899b3){this['QaaYHi']=_0x3899b3,this['MQHLKm']=[-0x1*0x19f+0x1*-0x639+0x11f*0x7,-0x44f*-0x5+0x9d8+-0x1f63*0x1,0x2385+0x3d1*-0x7+-0x8ce],this['TviRIm']=function(){return'newState';},this['osrHnW']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['LJNMdb']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x59e710['prototype']['aUWIYc']=function(){const _0x260e21=new RegExp(this['osrHnW']+this['LJNMdb']),_0x3dfc2c=_0x260e21['test'](this['TviRIm']['toString']())?--this['MQHLKm'][-0x3*0x4e4+-0xcc5*-0x3+0x37*-0x6e]:--this['MQHLKm'][0x1c05*-0x1+0xeb4+0xd51];return this['Zmqhqq'](_0x3dfc2c);},_0x59e710['prototype']['Zmqhqq']=function(_0x553109){if(!Boolean(~_0x553109))return _0x553109;return this['vaynce'](this['QaaYHi']);},_0x59e710['prototype']['vaynce']=function(_0x1e8f88){for(let _0x1f305d=0xc1*-0xe+0xfe6+-0x558,_0x281ad9=this['MQHLKm']['length'];_0x1f305d<_0x281ad9;_0x1f305d++){this['MQHLKm']['push'](Math['round'](Math['random']())),_0x281ad9=this['MQHLKm']['length'];}return _0x1e8f88(this['MQHLKm'][0x217a+-0x6c*0x8+-0x1e1a]);},new _0x59e710(_0x458a)['aUWIYc'](),_0x5d7574=_0x458a['KKhVGJ'](_0x5d7574),_0x458a['abvDsQ'][_0x2c9047]=_0x5d7574;}else _0x5d7574=_0x1fe2ce;return _0x5d7574;}import{config}from'../config.js';const HEARTBEAT_INTERVAL_MS=(0x9d*-0x2+-0xfed+0x112c)*(0x248b+-0x16fe+-0xd51*0x1)*(0x31c+-0xb8d*-0x1+-0x1*0xac1),HEARTBEAT_TIMEOUT_MS=-0x2d5b+0x7e*0x76+0x2ddf,FAIL_THRESHOLD=-0x236f+-0x13ba+0x1d*0x1e7,RECOVERY_THRESHOLD=0x1*0x25aa+0x9c3+-0x2f6c,POST_SLEEP_GRACE_MS=0x845f+0x6e01+0x80*-0x10,QUICK_RECOVERY_DELAY_MS=-0x193dc+-0x1*0xf0ec+-0xe*-0x3ecc,HEARTBEAT_PROVIDER=_0x151201(0xfd),state={'providers':new Map(),'intervalId':null,'isRunning':![],'originalPrimary':'','wasFailedOver':![],'lastRunAt':0x0,'graceUntil':0x0,'quickRecoveryTimer':null};export function startHeartbeat(){const _0x42dd06=_0x151201,_0x422d6e=_0x151201;if(state[_0x42dd06(0x11e)])return;const _0x281a1f=getRegistry();state[_0x422d6e(0x126)+_0x42dd06(0xe9)]=_0x281a1f[_0x42dd06(0x111)+'ey'](),state[_0x42dd06(0x11e)]=!![],state[_0x42dd06(0xc6)]=Date[_0x42dd06(0x10b)](),state['graceUntil']=0x173b+0x149d*0x1+-0x2bd8;const _0x1b3e6d=[config['primaryPro'+_0x42dd06(0x11d)],...config[_0x422d6e(0xc0)+_0x42dd06(0xd5)]]['filter']((_0xe69372,_0x29bcda,_0x5d7574)=>_0x5d7574[_0x422d6e(0x110)](_0xe69372)===_0x29bcda);for(const _0x65165 of _0x1b3e6d){state['providers'][_0x422d6e(0xf5)](_0x65165,{'key':_0x65165,'healthy':!![],'lastCheck':0x0,'lastLatencyMs':0x0,'failCount':0x0});}console['log']('💓\x20Heartbea'+_0x422d6e(0xc4)+'started\x20('+HEARTBEAT_INTERVAL_MS/(0x3*0x319+0x454*0x3+0x1*-0x125f)+(_0x422d6e(0xf7)+',\x20')+_0x1b3e6d['length']+(_0x422d6e(0xe1)+')')),setTimeout(()=>{const _0xf66587=_0x42dd06,_0x2671e0=_0x422d6e;runHeartbeat(),state[_0xf66587(0xcb)]=setInterval(runHeartbeat,HEARTBEAT_INTERVAL_MS),state[_0x2671e0(0xcb)]?.[_0xf66587(0xef)]?.();},-0xdbfc+-0x65c9*-0x2+-0x42cd*-0x2);}export function stopHeartbeat(){const _0x2ad864=_0x151201,_0x34131a=_0x151201;state[_0x2ad864(0xcb)]&&(clearInterval(state[_0x2ad864(0xcb)]),state[_0x2ad864(0xcb)]=null),state[_0x2ad864(0xf9)+_0x34131a(0x129)]&&(clearTimeout(state['quickRecov'+_0x2ad864(0x129)]),state[_0x2ad864(0xf9)+'eryTimer']=null),state[_0x34131a(0x11e)]=![],console[_0x34131a(0xd3)](_0x2ad864(0xd6)+'t\x20monitor\x20'+'stopped');}export function getHealthStatus(){const _0x569827=_0x151201,_0x3445bb=_0x151201;return Array[_0x569827(0xca)](state['providers'][_0x3445bb(0xd8)]())['map'](_0x49bb57=>({'key':_0x49bb57[_0x3445bb(0xea)],'healthy':_0x49bb57[_0x569827(0xb9)],'latencyMs':_0x49bb57[_0x569827(0xe4)+_0x569827(0xe2)],'failCount':_0x49bb57['failCount'],'lastCheck':_0x49bb57[_0x3445bb(0xe8)]?new Date(_0x49bb57['lastCheck'])['toISOStrin'+'g']():_0x569827(0x119),'lastError':_0x49bb57['lastError']}));}export function getFallbackOrder(){const _0x259c47=_0x151201,_0x4d19c4=_0x151201;return config[_0x259c47(0xc0)+_0x259c47(0xd5)];}export function isFailedOver(){const _0x30fb89=_0x151201,_0x57a31b=_0x151201;return state[_0x30fb89(0xdc)+_0x57a31b(0x108)];}async function runHeartbeat(){const _0xca8cf3=_0x151201,_0x1050cd=_0x151201,_0x2c9047=getRegistry(),_0x1fe2ce=Date[_0xca8cf3(0x10b)](),_0x25ce3c=_0x1fe2ce-state['lastRunAt'],_0x6ff257=state['lastRunAt']>-0x172*-0xb+0x2*-0x7c1+-0x64&&_0x25ce3c>HEARTBEAT_INTERVAL_MS*(-0x14*0x102+0x1373+-0x3d*-0x3);if(_0x6ff257){const _0xf8787b=Math[_0x1050cd(0x117)](_0x25ce3c/(-0xe543+-0x887d+0x25820));console['log'](_0x1050cd(0xda)+_0x1050cd(0x10c)+'~'+_0xf8787b+(_0x1050cd(0xcd)+_0x1050cd(0xe6)+_0xca8cf3(0x12c))+POST_SLEEP_GRACE_MS/(-0x1*-0x1c2b+0x2377+-0x3bba)+(_0xca8cf3(0x112)+'es\x20won\x27t\x20c'+'ount.')),state[_0xca8cf3(0xfc)]=_0x1fe2ce+POST_SLEEP_GRACE_MS;for(const [_0x16ccd9]of state[_0xca8cf3(0xfe)]){const _0x52e698=_0x2c9047[_0x1050cd(0x11b)](_0x16ccd9);_0x52e698&&typeof _0x52e698[_0x1050cd(0x105)+_0xca8cf3(0xbd)+_0x1050cd(0x101)]===_0x1050cd(0x116)&&_0x52e698[_0x1050cd(0x105)+_0xca8cf3(0xbd)+_0x1050cd(0x101)]();}for(const [,_0x56aea4]of state[_0x1050cd(0xfe)]){!_0x56aea4['healthy']&&(_0x56aea4['failCount']=-0x1*0x19f+0x1*-0x639+0x1f6*0x4,_0x56aea4['healthy']=!![],console[_0xca8cf3(0xd3)](_0xca8cf3(0x100)+_0x56aea4[_0x1050cd(0xea)]+(_0xca8cf3(0xba)+_0x1050cd(0x124)+_0x1050cd(0x120)+_0xca8cf3(0x11f))));}}state[_0xca8cf3(0xc6)]=_0x1fe2ce;const _0x2de94d=_0x1fe2ce<state[_0xca8cf3(0xfc)];for(const [_0x3ee40c,_0x4a4abd]of state[_0x1050cd(0xfe)]){const _0x3e6fac=_0x2c9047['get'](_0x3ee40c);if(!_0x3e6fac)continue;if(_0x3e6fac[_0x1050cd(0xdf)]){_0x4a4abd[_0xca8cf3(0xb9)]=!![],_0x4a4abd[_0x1050cd(0xe8)]=Date['now'](),_0x4a4abd[_0x1050cd(0xe4)+_0xca8cf3(0xe2)]=-0x44f*-0x5+0x9d8+-0x1f63*0x1,_0x4a4abd[_0x1050cd(0x118)]=0x2385+0x3d1*-0x7+-0x8ce,_0x4a4abd[_0x1050cd(0xc3)]=undefined;continue;}const _0x209ac5=Date[_0x1050cd(0x10b)]();try{const _0x59e710=await Promise[_0xca8cf3(0xed)]([_0x3e6fac['isAvailabl'+'e'](),new Promise((_0x260e21,_0x3dfc2c)=>setTimeout(()=>_0x3dfc2c(new Error(_0xca8cf3(0xbc))),HEARTBEAT_TIMEOUT_MS))]);if(!_0x59e710)throw new Error('Provider\x20r'+'eported\x20un'+_0x1050cd(0xd0));const _0x3899b3=await Promise[_0x1050cd(0xed)]([pingProvider(_0x3e6fac,_0x3ee40c),new Promise((_0x553109,_0x1e8f88)=>setTimeout(()=>_0x1e8f88(new Error(_0x1050cd(0xbc))),HEARTBEAT_TIMEOUT_MS))]);_0x4a4abd[_0xca8cf3(0xb9)]=!![],_0x4a4abd['lastLatenc'+_0xca8cf3(0xe2)]=Date[_0x1050cd(0x10b)]()-_0x209ac5,_0x4a4abd[_0xca8cf3(0xe8)]=Date['now'](),_0x4a4abd[_0x1050cd(0xc3)]=undefined,_0x4a4abd[_0x1050cd(0x118)]>-0x3*0x4e4+-0xcc5*-0x3+0x3*-0x7e1&&console[_0x1050cd(0xd3)](_0xca8cf3(0x115)+_0x3ee40c+(_0xca8cf3(0xe7)+_0xca8cf3(0xff))+_0x4a4abd[_0x1050cd(0xe4)+_0xca8cf3(0xe2)]+_0x1050cd(0x123)),_0x4a4abd[_0x1050cd(0x118)]=0x1c05*-0x1+0xeb4+0xd51;}catch(_0x1f305d){_0x4a4abd[_0x1050cd(0xe4)+_0xca8cf3(0xe2)]=Date[_0x1050cd(0x10b)]()-_0x209ac5,_0x4a4abd[_0x1050cd(0xe8)]=Date['now'](),_0x4a4abd[_0x1050cd(0xc3)]=_0x1f305d instanceof Error?_0x1f305d[_0x1050cd(0xc9)]:String(_0x1f305d);if(_0x2de94d){console[_0xca8cf3(0xd3)]('💓\x20😴\x20'+_0x3ee40c+(_0xca8cf3(0xcf)+_0xca8cf3(0xeb)+'g\x20grace\x20pe'+_0x1050cd(0xee))+_0x4a4abd[_0xca8cf3(0xc3)]+(_0xca8cf3(0x102)+'unting'));continue;}_0x4a4abd[_0x1050cd(0x118)]++,_0x4a4abd[_0xca8cf3(0x118)]>=FAIL_THRESHOLD?(_0x4a4abd['healthy']=![],console[_0xca8cf3(0xd3)](_0x1050cd(0x113)+_0x3ee40c+(_0x1050cd(0x11a)+'y\x20(')+_0x4a4abd[_0xca8cf3(0x118)]+(_0xca8cf3(0xd4)+'\x20')+_0x4a4abd['lastError']+')')):console[_0x1050cd(0xd3)](_0xca8cf3(0x121)+_0x3ee40c+_0xca8cf3(0xf0)+_0x4a4abd['failCount']+'/'+FAIL_THRESHOLD+'\x20('+_0x4a4abd[_0x1050cd(0xc3)]+')');}}await handleFailover(_0x2c9047);}async function pingProvider(_0x281ad9,_0x21f246){const _0x31384b=_0x151201,_0x210cb3=_0x151201;if(_0x21f246===_0x31384b(0x122)||_0x21f246==='codex-cli'){const _0x25af80=await _0x281ad9[_0x210cb3(0xb8)+'e']();return _0x25af80?'ok':_0x210cb3(0xfb)+'e';}let _0x2699b2='';for await(const _0x508515 of _0x281ad9['query']({'prompt':'Hi','systemPrompt':_0x210cb3(0xf8)+_0x210cb3(0x103)+'ok','history':[]})){if(_0x508515[_0x31384b(0x127)]===_0x31384b(0xc2))_0x2699b2=_0x508515[_0x31384b(0xc2)];if(_0x508515[_0x31384b(0x127)]===_0x210cb3(0x10a))return _0x2699b2||'ok';if(_0x508515['type']==='error')throw new Error(_0x508515[_0x210cb3(0x114)]);}return _0x2699b2||'ok';}async function handleFailover(_0x4f0365){const _0x53d656=_0x151201,_0x143321=_0x151201,_0x280cde=state[_0x53d656(0xfe)]['get'](state[_0x53d656(0x126)+_0x53d656(0xe9)]),_0x47a444=_0x4f0365['getActiveK'+'ey']();if(_0x280cde&&!_0x280cde[_0x143321(0xb9)]&&_0x47a444===state['originalPr'+_0x143321(0xe9)]){const _0x3620bc=config['fallbackPr'+_0x53d656(0xd5)];for(const _0x5e591b of _0x3620bc){const _0x1c7513=state[_0x143321(0xfe)][_0x143321(0x11b)](_0x5e591b);if(!_0x1c7513?.[_0x143321(0xb9)])continue;const _0x26615e=_0x4f0365[_0x143321(0x11b)](_0x5e591b);if(!_0x26615e)continue;if(_0x26615e[_0x143321(0xdf)]){console[_0x53d656(0xd3)](_0x53d656(0x107)+_0x53d656(0xdb)+state['originalPr'+_0x143321(0xe9)]+'\x20→\x20'+_0x5e591b+(_0x53d656(0xe3)+'\x20')+_0x5e591b+'…');const _0x3da8df=await _0x26615e[_0x143321(0xdf)][_0x143321(0x12d)+_0x143321(0xfa)]();if(!_0x3da8df){console['log'](_0x143321(0x121)+_0x5e591b+(_0x143321(0xd1)+_0x143321(0xc1)+'ing'));continue;}}else console[_0x143321(0xd3)]('💓\x20🔄\x20Auto-f'+_0x53d656(0xdb)+state['originalPr'+_0x143321(0xe9)]+_0x143321(0xc5)+_0x5e591b);_0x4f0365[_0x53d656(0x104)](_0x5e591b),state[_0x143321(0xdc)+'ver']=!![],scheduleQuickRecovery();return;}console[_0x143321(0xd3)]('💓\x20⚠️\x20All\x20pr'+'oviders\x20un'+_0x143321(0xde)+_0x143321(0xe5)+_0x53d656(0x10e));return;}if(_0x280cde?.[_0x53d656(0xb9)]&&state[_0x143321(0xdc)+'ver']&&_0x47a444!==state[_0x53d656(0x126)+_0x53d656(0xe9)]){const _0x26c3e1=_0x4f0365[_0x53d656(0x11b)](_0x47a444);console[_0x143321(0xd3)](_0x53d656(0xf2)+_0x53d656(0x12b)+'d\x20—\x20switch'+_0x143321(0xdd)+'o\x20'+state[_0x53d656(0x126)+_0x53d656(0xe9)]),_0x4f0365[_0x53d656(0x104)](state['originalPr'+_0x143321(0xe9)]),state['wasFailedO'+'ver']=![],_0x26c3e1?.[_0x53d656(0xdf)]&&(console[_0x53d656(0xd3)](_0x53d656(0x12a)+_0x143321(0xf3)+_0x47a444+(_0x143321(0x11c)+'unloading\x20'+_0x53d656(0x128))),await _0x26c3e1[_0x53d656(0xdf)][_0x143321(0xbb)+_0x53d656(0xbf)]());}}function scheduleQuickRecovery(){const _0x67bcef=_0x151201,_0x589848=_0x151201;state[_0x67bcef(0xf9)+_0x589848(0x129)]&&clearTimeout(state['quickRecov'+'eryTimer']),console['log'](_0x67bcef(0xce)+_0x67bcef(0xec)+_0x589848(0x10d)+_0x589848(0xd7)+QUICK_RECOVERY_DELAY_MS/(0xc1*-0xe+0xfe6+-0x170)+'s'),state[_0x589848(0xf9)+_0x67bcef(0x129)]=setTimeout(async()=>{const _0x50dd43=_0x67bcef,_0x49de04=_0x589848;state[_0x50dd43(0xf9)+_0x50dd43(0x129)]=null;if(!state[_0x49de04(0xdc)+'ver']||!state[_0x50dd43(0x11e)])return;console[_0x49de04(0xd3)]('💓\x20⏱️\x20Quick\x20'+_0x49de04(0xec)+'robe\x20firin'+'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(_0x1b0dc6,_0x9300ab){const _0x3c1058=_0x5f30,_0x2d05c0=_0x5f30,_0x30919a=_0x1b0dc6();while(!![]){try{const _0x3ee6e1=-parseInt(_0x3c1058(0xd8))/(0x18e6+0x1277*-0x2+0xc09*0x1)*(parseInt(_0x3c1058(0xe9))/(-0x1dc4+-0xd07*0x1+0x2acd*0x1))+-parseInt(_0x2d05c0(0xf4))/(-0x21cd+0x1425+0xdab)+-parseInt(_0x3c1058(0xed))/(-0x1752+-0x1607+0x2d5d)+parseInt(_0x2d05c0(0xec))/(0x1f5c+0x11e0+-0x3137)+-parseInt(_0x3c1058(0xd9))/(-0x15a1+-0x1*-0x1405+0x1a2)*(parseInt(_0x3c1058(0xdd))/(-0x6d*0x29+0xf93+-0x3*-0xa3))+-parseInt(_0x3c1058(0xef))/(0x169+0x3*0x7ac+-0x1865)+parseInt(_0x2d05c0(0xe4))/(0xb9b+-0x1ed7+-0x1345*-0x1)*(parseInt(_0x2d05c0(0xf2))/(0xc34+-0x22*-0x62+-0x192e));if(_0x3ee6e1===_0x9300ab)break;else _0x30919a['push'](_0x30919a['shift']());}catch(_0x5217cf){_0x30919a['push'](_0x30919a['shift']());}}}(_0x3222,0x22be7+-0x1*-0x37696+-0x3dbaf));function _0x5f30(_0x1add35,_0xf0269f){_0x1add35=_0x1add35-(0x2b*-0x6f+0xac0+0x8bc*0x1);const _0x1e5783=_0x3222();let _0x154a39=_0x1e5783[_0x1add35];if(_0x5f30['SbxxTU']===undefined){var _0x481f00=function(_0x1d84d8){const _0x1a6147='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x42b2ef='',_0x311c65='',_0x10cba8=_0x42b2ef+_0x481f00;for(let _0xbe90f9=-0x38b+0x2c3+0x4*0x32,_0x4ba637,_0x20b44c,_0x316903=-0x1325+-0x15f0+0x2915;_0x20b44c=_0x1d84d8['charAt'](_0x316903++);~_0x20b44c&&(_0x4ba637=_0xbe90f9%(-0x1fed+0x247b+-0x48a)?_0x4ba637*(-0x12e*-0x7+0x1*0x1999+-0x4cd*0x7)+_0x20b44c:_0x20b44c,_0xbe90f9++%(0x35a+-0xd35+-0x7*-0x169))?_0x42b2ef+=_0x10cba8['charCodeAt'](_0x316903+(-0x19ab*-0x1+0x21ff*-0x1+0x85e))-(-0x25a3+-0x270b+-0x8*-0x997)!==-0x746+0x8b+0x6bb?String['fromCharCode'](-0x12d+0x2470+0x1*-0x2244&_0x4ba637>>(-(-0x4*0x70f+0x2d+0x95b*0x3)*_0xbe90f9&0x17c2*0x1+0x2*0x60b+-0x51e*0x7)):_0xbe90f9:0x32a+0x19f7+-0x1d21){_0x20b44c=_0x1a6147['indexOf'](_0x20b44c);}for(let _0x4bc72a=0x1d39+0x243*0x2+-0x21bf,_0x356c51=_0x42b2ef['length'];_0x4bc72a<_0x356c51;_0x4bc72a++){_0x311c65+='%'+('00'+_0x42b2ef['charCodeAt'](_0x4bc72a)['toString'](0x2f*-0x9a+-0x1af7+0x374d))['slice'](-(-0x155*-0x19+-0x1*0x25ea+0x49f));}return decodeURIComponent(_0x311c65);};_0x5f30['eeYXeJ']=_0x481f00,_0x5f30['sIhmIR']={},_0x5f30['SbxxTU']=!![];}const _0x2f8709=_0x1e5783[-0x1428+-0x1e73+0x329b],_0x4139e3=_0x1add35+_0x2f8709,_0x2d28c0=_0x5f30['sIhmIR'][_0x4139e3];if(!_0x2d28c0){const _0x5e1914=function(_0x37e122){this['KTldch']=_0x37e122,this['WsyHTV']=[-0x715+0x155*-0x5+0xdbf,0x2444*0x1+-0x257e+-0x1*-0x13a,0xa2*-0x1f+-0x84d+0x1beb],this['ESUHBt']=function(){return'newState';},this['gPsaos']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['pcCFJs']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x5e1914['prototype']['TanSKB']=function(){const _0x60c74a=new RegExp(this['gPsaos']+this['pcCFJs']),_0x3ddadd=_0x60c74a['test'](this['ESUHBt']['toString']())?--this['WsyHTV'][0x1652*0x1+0x1db7+-0x3408]:--this['WsyHTV'][-0x27+0x3a5*0x9+-0x20a6];return this['vmvALv'](_0x3ddadd);},_0x5e1914['prototype']['vmvALv']=function(_0xa0c6cc){if(!Boolean(~_0xa0c6cc))return _0xa0c6cc;return this['OYWUfq'](this['KTldch']);},_0x5e1914['prototype']['OYWUfq']=function(_0xa5ef71){for(let _0x23ceb4=0x1425+-0x1303+-0x122,_0x52679f=this['WsyHTV']['length'];_0x23ceb4<_0x52679f;_0x23ceb4++){this['WsyHTV']['push'](Math['round'](Math['random']())),_0x52679f=this['WsyHTV']['length'];}return _0xa5ef71(this['WsyHTV'][-0x1607+-0x59d+0x3d*0x74]);},new _0x5e1914(_0x5f30)['TanSKB'](),_0x154a39=_0x5f30['eeYXeJ'](_0x154a39),_0x5f30['sIhmIR'][_0x4139e3]=_0x154a39;}else _0x154a39=_0x2d28c0;return _0x154a39;}const _0x24643d=(function(){let _0x39c487=!![];return function(_0x4eee02,_0x3ff90e){const _0xe6a95d=_0x39c487?function(){const _0x2b1e4e=_0x5f30;if(_0x3ff90e){const _0x4cd06a=_0x3ff90e[_0x2b1e4e(0xdc)](_0x4eee02,arguments);return _0x3ff90e=null,_0x4cd06a;}}:function(){};return _0x39c487=![],_0xe6a95d;};}()),_0x41d19e=_0x24643d(this,function(){const _0x39b63f=_0x5f30,_0x104c11=_0x5f30;return _0x41d19e['toString']()[_0x39b63f(0xf6)](_0x104c11(0xe0)+'+$')['toString']()[_0x39b63f(0xea)+'r'](_0x41d19e)[_0x39b63f(0xf6)](_0x39b63f(0xe0)+'+$');});_0x41d19e();import{readdirSync,existsSync}from'fs';import{resolve}from'path';function _0x3222(){const _0x45befe=['mtm4vvbjvvHc','y29UC3rYDwn0BW','rMfPBgvKihrVia','mta0nteXmfv3AgLcsW','nZu0mZK2z3furgTv','zdOG','mZq2oteYDhD2DNvl','BMfTzq','AgfUzgXLCG','ntCXotiXmgnhDM11qW','BwfW','mZG4otmYqKTNq1jQ','Bg9N','C2vHCMnO','ChvZAa','mZm3m2Hbwhv0vW','ndiXmde0BMnxyuvN','Bg9HzcbOB29Ria','zMLSDgvY','yxbWBhK','n055zg1MCW','DgHLBG','zxjYB3i','kcGOlISPkYKRkq','zw5KC1DPDgG','lM1QCW','lMPZ','ovvQwwjowq','zxzLBNq','sg9VAYbLCNjVCG','zNvUy3rPB24','y2f0y2G'];_0x3222=function(){return _0x45befe;};return _0x3222();}import{HOOKS_DIR}from'../paths.js';const registry=[];export function registerHook(_0x4423d4){const _0x15eda0=_0x5f30;registry[_0x15eda0(0xd7)](_0x4423d4);}export async function emit(_0x397ff9,_0x124455={}){const _0x3899d0=_0x5f30,_0x5220f1=_0x5f30,_0x33c727=registry[_0x3899d0(0xdb)](_0x1f9152=>_0x1f9152[_0x5220f1(0xe5)]===_0x397ff9);for(const _0x1809d8 of _0x33c727){try{await _0x1809d8[_0x3899d0(0xf1)]({..._0x124455,'_event':_0x397ff9,'_timestamp':Date['now']()});}catch(_0x190e1b){console[_0x5220f1(0xdf)](_0x5220f1(0xe6)+'\x20('+_0x1809d8[_0x5220f1(0xf0)]+'/'+_0x397ff9+'):',_0x190e1b);}}}export function loadHooks(){const _0x395bb2=_0x5f30,_0x21e240=_0x5f30;if(!existsSync(HOOKS_DIR))return-0x1325+-0x15f0+0x2915;const _0x56f6b9=readdirSync(HOOKS_DIR)[_0x395bb2(0xdb)](_0x4f0424=>_0x4f0424[_0x395bb2(0xe1)](_0x395bb2(0xe3))||_0x4f0424[_0x21e240(0xe1)](_0x395bb2(0xe2)));let _0x224782=-0x1fed+0x247b+-0x48e;for(const _0x631f3c of _0x56f6b9){try{const _0x5eb8bd=resolve(HOOKS_DIR,_0x631f3c);import(_0x5eb8bd)[_0x21e240(0xde)](_0x180f44=>{const _0xd97adc=_0x21e240,_0xfe618e=_0x21e240;_0x180f44[_0xd97adc(0xe5)]&&typeof _0x180f44[_0xfe618e(0xf1)]===_0xd97adc(0xe7)&&(registerHook({'event':_0x180f44[_0xd97adc(0xe5)],'name':_0x631f3c,'handler':_0x180f44['handler']}),console[_0xfe618e(0xf5)]('Hook\x20loade'+_0xd97adc(0xee)+_0x631f3c+'\x20→\x20'+_0x180f44[_0xfe618e(0xe5)]));})[_0x21e240(0xe8)](_0x49ee66=>console[_0x395bb2(0xdf)](_0x395bb2(0xeb)+_0x21e240(0xda)+_0x631f3c+':',_0x49ee66)),_0x224782++;}catch(_0x5e4d29){console[_0x21e240(0xdf)]('Failed\x20to\x20'+_0x395bb2(0xda)+_0x631f3c+':',_0x5e4d29);}}return _0x224782;}export function getRegisteredHooks(){const _0x5e9066=_0x5f30,_0x2b1c58=_0x5f30;return registry[_0x5e9066(0xf3)](_0x2ba4f5=>({'event':_0x2ba4f5[_0x5e9066(0xe5)],'name':_0x2ba4f5[_0x2b1c58(0xf0)]}));}
|
|
@@ -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 _0xddfba9=_0x2223,_0x45c932=_0x2223;(function(_0x5450f6,_0x5d06f5){const _0x5ee1a7=_0x2223,_0x32cc59=_0x2223,_0x277fc9=_0x5450f6();while(!![]){try{const _0x441042=parseInt(_0x5ee1a7(0x1f8))/(-0xb7*0x1+-0x2187+0x223f)+parseInt(_0x32cc59(0x216))/(0x3*-0x897+-0x1*0xf9d+0x2964)*(-parseInt(_0x32cc59(0x207))/(0xf93+-0x11f2+-0x2*-0x131))+-parseInt(_0x32cc59(0x200))/(-0x117f+0x2181+-0xffe)+-parseInt(_0x5ee1a7(0x20b))/(0x1837+-0x71f*-0x1+-0x1f51)*(-parseInt(_0x5ee1a7(0x205))/(-0x70a+0x1a0f+-0x12ff*0x1))+parseInt(_0x32cc59(0x1e9))/(-0x491+0x176e+-0x12d6*0x1)*(-parseInt(_0x32cc59(0x1f2))/(-0x37d*0x1+0x1*-0x1cc9+0x676*0x5))+-parseInt(_0x5ee1a7(0x1e8))/(0x1c8b+-0x3*0x19b+0x5*-0x4bd)*(parseInt(_0x5ee1a7(0x1e0))/(0xe1e*-0x1+-0x13ae*-0x1+-0x586))+-parseInt(_0x5ee1a7(0x217))/(0x6bc+-0x505+-0x4*0x6b)*(-parseInt(_0x32cc59(0x1de))/(-0x2294+-0x123b*-0x1+0x1065));if(_0x441042===_0x5d06f5)break;else _0x277fc9['push'](_0x277fc9['shift']());}catch(_0x297b38){_0x277fc9['push'](_0x277fc9['shift']());}}}(_0x3a6b,0x11669b+0x3*0x1ec79+-0x438b*0x35));const _0x21ee16=(function(){let _0x59ac6f=!![];return function(_0x5e428d,_0x53925a){const _0x166231=_0x59ac6f?function(){const _0x58fd4f=_0x2223;if(_0x53925a){const _0x47da82=_0x53925a[_0x58fd4f(0x1dc)](_0x5e428d,arguments);return _0x53925a=null,_0x47da82;}}:function(){};return _0x59ac6f=![],_0x166231;};}()),_0x58b580=_0x21ee16(this,function(){const _0x1539c9=_0x2223,_0x1e4933=_0x2223;return _0x58b580[_0x1539c9(0x212)]()[_0x1539c9(0x202)](_0x1539c9(0x1e3)+'+$')[_0x1539c9(0x212)]()[_0x1539c9(0x214)+'r'](_0x58b580)['search'](_0x1539c9(0x1e3)+'+$');});_0x58b580();import _0x505f60 from'fs';function _0x3a6b(){const _0x373130=['BgvKoIa','lNbUzW','zw5LCMf0zwq','yxbWBhK','r2vTAw5Piefqsq','nJbtuefmv0W','Dg1WzgLY','mtbcu2DivLq','BwLTzvr5Cgu','z2vTAw5PltiUma','kcGOlISPkYKRkq','lwzSyxnOlwv4Ca','zNjVBq','tM8GAw1Hz2uGzW','BIbPBwfNztOG','otiXotG1mMzcBMvprq','n2DpAvvQqG','B250zw50p2TLEq','BM93','BwvZC2fNzq','BMvYyxrPDMvSyq','oMDLBMvYyxrLqW','D3jPDgvgAwXLuW','C3rHDhvZ','AM9PBG','oti5nZa5nLrkwhvsBq','zgf0yq','ywX2Aw4TyM90','yxbWBgLJyxrPBW','y29UDgvUDa','C3rYAw5NAwz5','mta2mdm5nMH2BKLevW','z2XLyxbPCY5JBW','x0TfwsbUB3qGyW','r2vUzxjHDguGyq','zxHPC3rZu3LUyW','r09pr0Xfx0fqsq','vevyva','Aw5SAw5Lrgf0yq','mJG2nduWmfjsreTnAW','tM8GCMvZCg9UCW','C2vHCMnO','zsbMCM9TieDLBq','yMfZzty0','mtHPuu5tAgG','Aw5P','mZi3nZaXmwDYtLfYCq','ue9tva','B25MAwD1CMvK','CMf0Aw9UigzHAq','mta4nZK2mfLbBNroEq','Aw1Hz2uVCg5N','z2vUxW','CgfYDhm','Dgv4Da','BMD1ywDLlMDVBW','Bs92mwjLDgeVBq','Dg9tDhjPBMC','vw5RBM93BIbLCG','y29UC3rYDwn0BW','CM9Y','mKrNEuDsyW','nJm0ndG2nNPNugnRza','BwTKAxjtEw5J'];_0x3a6b=function(){return _0x373130;};return _0x3a6b();}import _0x2da67c from'path';import _0x360e4e from'os';const TEMP_DIR=_0x2da67c['join'](_0x360e4e[_0xddfba9(0x1df)](),_0xddfba9(0x1f4));if(!_0x505f60[_0xddfba9(0x1fc)](TEMP_DIR))_0x505f60[_0xddfba9(0x218)](TEMP_DIR,{'recursive':!![]});function _0x2223(_0x4d3ea1,_0x386102){_0x4d3ea1=_0x4d3ea1-(0x25ec+-0x29*0xad+-0x5*0x1ac);const _0x208cb3=_0x3a6b();let _0x43ec39=_0x208cb3[_0x4d3ea1];if(_0x2223['DlURNV']===undefined){var _0xabc838=function(_0x547a9e){const _0x2fa7fd='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3a2455='',_0x3ef9b3='',_0x2a1dc4=_0x3a2455+_0xabc838;for(let _0x4c4943=0xe83*-0x1+0x14f9*-0x1+-0x5ea*-0x6,_0x265f82,_0x129c67,_0x393043=0x1afa+-0x3c0+-0x1*0x173a;_0x129c67=_0x547a9e['charAt'](_0x393043++);~_0x129c67&&(_0x265f82=_0x4c4943%(0x29c*0x2+0x2266+-0x279a*0x1)?_0x265f82*(0x18e5+-0x236*0xc+0x1e3)+_0x129c67:_0x129c67,_0x4c4943++%(-0x4df*0x1+-0x15a9+-0xd46*-0x2))?_0x3a2455+=_0x2a1dc4['charCodeAt'](_0x393043+(0x488+0x2265+-0x26e3*0x1))-(0x1*-0x213a+-0x4ef+-0x2633*-0x1)!==-0xdd1*-0x2+-0x5c*-0xa+-0x1f3a?String['fromCharCode'](0x1*-0x653+0x2*-0x970+0x1a32&_0x265f82>>(-(-0x104*0x2+0xa33+-0x829)*_0x4c4943&0x13ef+0x1901+0x1675*-0x2)):_0x4c4943:-0x35*-0x1d+0x1*0xf34+-0x1535){_0x129c67=_0x2fa7fd['indexOf'](_0x129c67);}for(let _0x2af8dc=-0xa57+0x1458+0xc5*-0xd,_0x2b6e52=_0x3a2455['length'];_0x2af8dc<_0x2b6e52;_0x2af8dc++){_0x3ef9b3+='%'+('00'+_0x3a2455['charCodeAt'](_0x2af8dc)['toString'](0x1b8b+-0x1c6a+-0xef*-0x1))['slice'](-(0x46a*0x7+0x1969*-0x1+-0x57b));}return decodeURIComponent(_0x3ef9b3);};_0x2223['FnmYZm']=_0xabc838,_0x2223['hiPgyW']={},_0x2223['DlURNV']=!![];}const _0x2eb7a4=_0x208cb3[0x19d4+-0x43*0x4b+-0x633],_0x27188c=_0x4d3ea1+_0x2eb7a4,_0x4f7e5f=_0x2223['hiPgyW'][_0x27188c];if(!_0x4f7e5f){const _0xc8e418=function(_0x4dd6c3){this['FKMwqp']=_0x4dd6c3,this['mJuOSW']=[0x329*0x7+0x731+0x9c5*-0x3,0x1d12+-0x85*0x1+-0x1c8d,0x1*-0x214d+0x96a*0x3+-0x1*-0x50f],this['xNYtxH']=function(){return'newState';},this['DhgBBb']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['SVYwoc']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0xc8e418['prototype']['jDMELe']=function(){const _0x66b77b=new RegExp(this['DhgBBb']+this['SVYwoc']),_0x4d87da=_0x66b77b['test'](this['xNYtxH']['toString']())?--this['mJuOSW'][-0x2187+0x5a6+0x1be2]:--this['mJuOSW'][0x3*-0x897+-0x1*0xf9d+0x2962];return this['hSJnUB'](_0x4d87da);},_0xc8e418['prototype']['hSJnUB']=function(_0x39559b){if(!Boolean(~_0x39559b))return _0x39559b;return this['bToSxB'](this['FKMwqp']);},_0xc8e418['prototype']['bToSxB']=function(_0x539ee0){for(let _0x51194e=0xf93+-0x11f2+-0x1*-0x25f,_0x52864d=this['mJuOSW']['length'];_0x51194e<_0x52864d;_0x51194e++){this['mJuOSW']['push'](Math['round'](Math['random']())),_0x52864d=this['mJuOSW']['length'];}return _0x539ee0(this['mJuOSW'][-0x117f+0x2181+-0x1002]);},new _0xc8e418(_0x2223)['jDMELe'](),_0x43ec39=_0x2223['FnmYZm'](_0x43ec39),_0x2223['hiPgyW'][_0x27188c]=_0x43ec39;}else _0x43ec39=_0x4f7e5f;return _0x43ec39;}const MODEL=_0xddfba9(0x1e2)+_0x45c932(0x1e4),API_URL='https://ge'+_0x45c932(0x1ed)+_0xddfba9(0x210)+_0x45c932(0x1f9)+_0xddfba9(0x211)+'odels';export async function generateImage(_0x9a00e,_0x4e12f1){const _0x1b8d2b=_0x45c932,_0x2f5815=_0x45c932;if(!_0x4e12f1)return{'success':![],'error':_0x1b8d2b(0x1fd)+_0x2f5815(0x1fa)+_0x1b8d2b(0x209)};try{const _0xf4e952=API_URL+'/'+MODEL+(_0x1b8d2b(0x1ee)+_0x1b8d2b(0x1ea)+'=')+_0x4e12f1,_0x127a78=await fetch(_0xf4e952,{'method':_0x1b8d2b(0x208),'headers':{'Content-Type':_0x1b8d2b(0x1f5)+'n/json'},'body':JSON[_0x2f5815(0x1f7)]({'contents':[{'parts':[{'text':_0x1b8d2b(0x1fb)+_0x1b8d2b(0x1e7)+_0x9a00e}]}],'generationConfig':{'responseModalities':['IMAGE',_0x1b8d2b(0x1fe)]}})});if(!_0x127a78['ok']){const _0x29be70=await _0x127a78[_0x1b8d2b(0x20f)]()['catch'](()=>_0x1b8d2b(0x213)+_0x1b8d2b(0x215));return{'success':![],'error':_0x2f5815(0x1dd)+'\x20error\x20('+_0x127a78[_0x1b8d2b(0x1f0)]+'):\x20'+_0x29be70};}const _0x481d31=await _0x127a78['json'](),_0x1493d5=_0x481d31['candidates']?.[-0x2*-0x297+-0x19a5+0x1477]?.[_0x2f5815(0x1f6)]?.[_0x1b8d2b(0x20e)];if(!_0x1493d5)return{'success':![],'error':_0x1b8d2b(0x201)+_0x2f5815(0x203)+_0x1b8d2b(0x206)};for(const _0x154058 of _0x1493d5){if(_0x154058[_0x1b8d2b(0x1ff)]?.[_0x2f5815(0x1f3)]){const _0x34a5fe=_0x154058[_0x2f5815(0x1ff)][_0x2f5815(0x1e1)]===_0x1b8d2b(0x20c)?_0x2f5815(0x21a):'.jpg',_0x5b4c18=_0x2da67c[_0x1b8d2b(0x1f1)](TEMP_DIR,_0x2f5815(0x20d)+Date[_0x1b8d2b(0x1eb)]()+_0x34a5fe),_0x20883e=Buffer[_0x2f5815(0x1e5)](_0x154058[_0x2f5815(0x1ff)][_0x2f5815(0x1f3)],_0x2f5815(0x204));return _0x505f60[_0x2f5815(0x1ef)+'ync'](_0x5b4c18,_0x20883e),{'success':!![],'filePath':_0x5b4c18,'mimeType':_0x154058[_0x2f5815(0x1ff)]['mimeType']};}}const _0x1dd996=_0x1493d5['find'](_0x572c09=>_0x572c09[_0x1b8d2b(0x20f)]);return{'success':![],'error':_0x1dd996?.[_0x1b8d2b(0x20f)]||_0x1b8d2b(0x1e6)+_0x2f5815(0x1db)};}catch(_0xce3437){return{'success':![],'error':'Image\x20gene'+_0x1b8d2b(0x20a)+_0x1b8d2b(0x219)+(_0xce3437 instanceof Error?_0xce3437[_0x1b8d2b(0x1ec)]:String(_0xce3437))};}}
|