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.
Files changed (137) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/dist/claude.js +1 -102
  4. package/dist/config.js +1 -96
  5. package/dist/engine.js +1 -90
  6. package/dist/find-claude-binary.js +1 -98
  7. package/dist/handlers/async-agent-chunk-handler.js +1 -50
  8. package/dist/handlers/background-bypass.js +1 -75
  9. package/dist/handlers/commands.js +1 -2336
  10. package/dist/handlers/cron-progress.js +1 -52
  11. package/dist/handlers/document.js +1 -194
  12. package/dist/handlers/message.js +1 -959
  13. package/dist/handlers/photo.js +1 -154
  14. package/dist/handlers/platform-message.js +1 -360
  15. package/dist/handlers/stuck-timer.js +1 -54
  16. package/dist/handlers/video.js +1 -237
  17. package/dist/handlers/voice.js +1 -148
  18. package/dist/i18n.js +1 -805
  19. package/dist/index.js +1 -697
  20. package/dist/init-data-dir.js +1 -98
  21. package/dist/middleware/auth.js +1 -233
  22. package/dist/migrate.js +1 -162
  23. package/dist/paths.js +1 -146
  24. package/dist/platforms/discord.js +1 -175
  25. package/dist/platforms/index.js +1 -130
  26. package/dist/platforms/signal.js +1 -205
  27. package/dist/platforms/slack-slash-parser.js +1 -32
  28. package/dist/platforms/slack.js +1 -501
  29. package/dist/platforms/telegram.js +1 -111
  30. package/dist/platforms/types.js +1 -8
  31. package/dist/platforms/whatsapp-auth-helpers.js +1 -53
  32. package/dist/platforms/whatsapp.js +1 -707
  33. package/dist/providers/claude-sdk-provider.js +1 -565
  34. package/dist/providers/codex-cli-provider.js +1 -134
  35. package/dist/providers/index.js +1 -7
  36. package/dist/providers/ollama-provider.js +1 -32
  37. package/dist/providers/openai-compatible.js +1 -406
  38. package/dist/providers/registry.js +1 -352
  39. package/dist/providers/runtime-header.js +1 -45
  40. package/dist/providers/tool-executor.js +1 -475
  41. package/dist/providers/types.js +1 -227
  42. package/dist/services/access.js +1 -144
  43. package/dist/services/allowed-users-gate.js +1 -56
  44. package/dist/services/alvin-dispatch.js +1 -130
  45. package/dist/services/alvin-mcp-tools.js +1 -104
  46. package/dist/services/asset-index.js +1 -224
  47. package/dist/services/async-agent-parser.js +1 -418
  48. package/dist/services/async-agent-watcher.js +1 -443
  49. package/dist/services/auto-diagnostic.js +1 -228
  50. package/dist/services/broadcast.js +1 -52
  51. package/dist/services/browser-manager.js +1 -562
  52. package/dist/services/browser-webfetch.js +1 -127
  53. package/dist/services/browser.js +1 -121
  54. package/dist/services/cdp-bootstrap.js +1 -357
  55. package/dist/services/compaction.js +1 -144
  56. package/dist/services/critical-notify.js +1 -203
  57. package/dist/services/cron-resolver.js +1 -58
  58. package/dist/services/cron-scheduling.js +1 -310
  59. package/dist/services/cron.js +1 -861
  60. package/dist/services/custom-tools.js +1 -317
  61. package/dist/services/delivery-queue.js +1 -173
  62. package/dist/services/delivery-registry.js +1 -21
  63. package/dist/services/disk-cleanup.js +1 -203
  64. package/dist/services/elevenlabs.js +1 -58
  65. package/dist/services/embeddings/auto-detect.js +1 -74
  66. package/dist/services/embeddings/fts5.js +1 -108
  67. package/dist/services/embeddings/gemini.js +1 -65
  68. package/dist/services/embeddings/index.js +1 -496
  69. package/dist/services/embeddings/ollama.js +1 -78
  70. package/dist/services/embeddings/openai.js +1 -49
  71. package/dist/services/embeddings/provider.js +1 -22
  72. package/dist/services/embeddings/vector-base.js +1 -113
  73. package/dist/services/embeddings-migration.js +1 -193
  74. package/dist/services/embeddings.js +1 -9
  75. package/dist/services/env-file.js +1 -50
  76. package/dist/services/exec-guard.js +1 -71
  77. package/dist/services/fallback-order.js +1 -154
  78. package/dist/services/file-permissions.js +1 -93
  79. package/dist/services/heartbeat-file.js +1 -65
  80. package/dist/services/heartbeat.js +1 -313
  81. package/dist/services/hooks.js +1 -44
  82. package/dist/services/imagegen.js +1 -72
  83. package/dist/services/language-detect.js +1 -154
  84. package/dist/services/markdown.js +1 -63
  85. package/dist/services/mcp.js +1 -263
  86. package/dist/services/memory-extractor.js +1 -178
  87. package/dist/services/memory-inject-mode.js +1 -43
  88. package/dist/services/memory-layers.js +1 -156
  89. package/dist/services/memory.js +1 -146
  90. package/dist/services/ollama-manager.js +1 -339
  91. package/dist/services/permissions-wizard.js +1 -291
  92. package/dist/services/personality.js +1 -376
  93. package/dist/services/plugins.js +1 -171
  94. package/dist/services/preflight.js +1 -292
  95. package/dist/services/process-manager.js +1 -291
  96. package/dist/services/release-highlights.js +1 -79
  97. package/dist/services/reminders.js +1 -97
  98. package/dist/services/restart.js +1 -48
  99. package/dist/services/security-audit.js +1 -74
  100. package/dist/services/self-diagnosis.js +1 -272
  101. package/dist/services/self-search.js +1 -129
  102. package/dist/services/session-persistence.js +1 -237
  103. package/dist/services/session.js +1 -282
  104. package/dist/services/skills.js +1 -290
  105. package/dist/services/ssrf-guard.js +1 -162
  106. package/dist/services/standing-orders.js +1 -29
  107. package/dist/services/steer-channel.js +1 -46
  108. package/dist/services/stop-controller.js +1 -52
  109. package/dist/services/subagent-dedup.js +1 -0
  110. package/dist/services/subagent-delivery.js +1 -452
  111. package/dist/services/subagent-stats.js +1 -123
  112. package/dist/services/subagents.js +1 -814
  113. package/dist/services/sudo.js +1 -329
  114. package/dist/services/telegram.js +1 -158
  115. package/dist/services/timing-safe-bearer.js +1 -51
  116. package/dist/services/tool-discovery.js +1 -214
  117. package/dist/services/trends.js +1 -580
  118. package/dist/services/updater.js +1 -291
  119. package/dist/services/usage-tracker.js +1 -144
  120. package/dist/services/users.js +1 -271
  121. package/dist/services/voice.js +1 -104
  122. package/dist/services/watchdog-brake.js +1 -154
  123. package/dist/services/watchdog.js +1 -311
  124. package/dist/services/workspaces.js +1 -276
  125. package/dist/tui/index.js +1 -667
  126. package/dist/util/console-formatter.js +1 -109
  127. package/dist/util/debounce.js +1 -24
  128. package/dist/util/telegram-error-filter.js +1 -62
  129. package/dist/version.js +1 -24
  130. package/dist/web/bind-strategy.js +1 -42
  131. package/dist/web/canvas.js +1 -30
  132. package/dist/web/doctor-api.js +1 -604
  133. package/dist/web/openai-compat.js +1 -252
  134. package/dist/web/server.js +1 -1831
  135. package/dist/web/setup-api.js +1 -1101
  136. package/package.json +5 -2
  137. 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);}
@@ -1,44 +1 @@
1
- import { readdirSync, existsSync } from "fs";
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))};}}