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,291 +1 @@
1
- /**
2
- * Updater Service — git-based self-update for alvin-bot.
3
- *
4
- * Provides:
5
- * - runUpdate(): manual update (git pull + install + build)
6
- * - getAutoUpdate() / setAutoUpdate(): persistent on/off toggle
7
- * - startAutoUpdateLoop(): periodic check every 6h if enabled
8
- *
9
- * After a successful update that produces new artifacts, the bot calls
10
- * process.exit(0) and relies on its supervising process manager to
11
- * restart it with fresh code (launchd KeepAlive, systemd Restart=, PM2,
12
- * Docker restart policy, etc.). This is the only safe self-restart path
13
- * — we never re-exec the Node process directly.
14
- *
15
- * The auto-update flag is persisted to ~/.alvin-bot/auto-update.flag
16
- * (a plain text file containing "on" or "off"), so it survives restarts.
17
- */
18
- import { exec } from "child_process";
19
- import { promisify } from "util";
20
- import { resolve, dirname } from "path";
21
- import { fileURLToPath } from "url";
22
- import fs from "fs";
23
- import os from "os";
24
- import { BOT_VERSION } from "../version.js";
25
- import { markExpectedRestart } from "./watchdog.js";
26
- const execAsync = promisify(exec);
27
- const PROJECT_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
28
- const DATA_DIR = process.env.ALVIN_DATA_DIR || resolve(os.homedir(), ".alvin-bot");
29
- const FLAG_FILE = resolve(DATA_DIR, "auto-update.flag");
30
- const AUTO_CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000; // 6 hours
31
- let autoTimer = null;
32
- /**
33
- * Is PROJECT_ROOT itself a git repository? We deliberately do NOT use
34
- * `git rev-parse --is-inside-work-tree` because that walks UP the
35
- * directory tree and would return true for any ancestor that happens
36
- * to be a git repo — e.g. Homebrew stores its formula tree in a git
37
- * repo at /opt/homebrew/, so a npm-global install of alvin-bot under
38
- * /opt/homebrew/lib/node_modules/alvin-bot would be reported as a git
39
- * repo even though it's just plain files shipped via npm.
40
- *
41
- * The strict check: does PROJECT_ROOT/.git exist?
42
- */
43
- function isOwnGitRepo() {
44
- return fs.existsSync(resolve(PROJECT_ROOT, ".git"));
45
- }
46
- /**
47
- * Heuristic for "this is an npm-global install": PROJECT_ROOT sits
48
- * inside a node_modules/alvin-bot directory. Covers:
49
- * - /opt/homebrew/lib/node_modules/alvin-bot (Homebrew node)
50
- * - /usr/local/lib/node_modules/alvin-bot (plain npm)
51
- * - ~/.nvm/versions/node/...alvin-bot (nvm)
52
- * - ~/.volta/tools/image/packages/...alvin-bot (volta)
53
- */
54
- function isNpmGlobalInstall() {
55
- return /node_modules[/\\]alvin-bot$/.test(PROJECT_ROOT) || PROJECT_ROOT.includes("node_modules/alvin-bot/");
56
- }
57
- function readLocalVersion() {
58
- try {
59
- const pkgPath = resolve(PROJECT_ROOT, "package.json");
60
- const raw = fs.readFileSync(pkgPath, "utf-8");
61
- const parsed = JSON.parse(raw);
62
- return parsed.version ?? null;
63
- }
64
- catch {
65
- return null;
66
- }
67
- }
68
- async function fetchRemoteVersion() {
69
- try {
70
- const { stdout } = await execAsync("npm view alvin-bot version", {
71
- timeout: 15_000,
72
- });
73
- return stdout.trim() || null;
74
- }
75
- catch {
76
- return null;
77
- }
78
- }
79
- /** Semver-compare A vs B. Returns negative if A < B, 0 if equal, positive if A > B. */
80
- function compareSemver(a, b) {
81
- const norm = (v) => v.replace(/^v/, "").split(/[.-]/).map((p) => parseInt(p, 10) || 0);
82
- const av = norm(a);
83
- const bv = norm(b);
84
- for (let i = 0; i < Math.max(av.length, bv.length); i++) {
85
- const diff = (av[i] ?? 0) - (bv[i] ?? 0);
86
- if (diff !== 0)
87
- return diff;
88
- }
89
- return 0;
90
- }
91
- /**
92
- * Is the running bot's in-memory version older than what's already built
93
- * on disk? This happens when the dev/CI rebuilt the bot mid-session and
94
- * the process hasn't restarted yet. A manual /update without a git/npm
95
- * fetch should still trigger a restart in this case so the fresh code
96
- * takes effect.
97
- */
98
- function isRuntimeStale() {
99
- const onDisk = readLocalVersion();
100
- if (!onDisk || !BOT_VERSION || BOT_VERSION === "unknown")
101
- return false;
102
- return compareSemver(BOT_VERSION, onDisk) < 0;
103
- }
104
- /** Pull latest changes, install deps, rebuild. Returns a structured result
105
- * instead of throwing so the /update command can report cleanly to Telegram.
106
- * Dispatches to the git path for source installs and the npm path for
107
- * npm-global installs.
108
- *
109
- * Before doing any fetch, checks whether the disk is already newer than
110
- * the running process (i.e. someone rebuilt between the process start
111
- * and this call). If so, returns success with requiresRestart=true so
112
- * the command handler can trigger a graceful restart.
113
- */
114
- export async function runUpdate() {
115
- try {
116
- // Stale-runtime check: disk is already newer than the running code.
117
- if (isRuntimeStale()) {
118
- const onDisk = readLocalVersion();
119
- return {
120
- ok: true,
121
- message: `Disk is already built at v${onDisk}, running v${BOT_VERSION}. Restarting to pick up the new code...`,
122
- requiresRestart: true,
123
- };
124
- }
125
- if (isOwnGitRepo()) {
126
- return await runGitUpdate();
127
- }
128
- if (isNpmGlobalInstall()) {
129
- return await runNpmUpdate();
130
- }
131
- return {
132
- ok: false,
133
- message: "Update not supported for this install type. Clone the git repo or use npm install -g alvin-bot.",
134
- requiresRestart: false,
135
- };
136
- }
137
- catch (err) {
138
- const raw = err instanceof Error ? err.message : String(err);
139
- const message = raw.length > 300 ? raw.slice(0, 300) + "…" : raw;
140
- return { ok: false, message, requiresRestart: false };
141
- }
142
- }
143
- async function runGitUpdate() {
144
- // Fetch latest without merging
145
- await execAsync("git fetch --quiet", {
146
- cwd: PROJECT_ROOT,
147
- timeout: 30_000,
148
- });
149
- // Count commits we're behind the upstream
150
- let behindCount = 0;
151
- try {
152
- const { stdout } = await execAsync("git rev-list --count HEAD..@{upstream}", {
153
- cwd: PROJECT_ROOT,
154
- timeout: 10_000,
155
- });
156
- behindCount = parseInt(stdout.trim() || "0", 10);
157
- }
158
- catch {
159
- behindCount = 0;
160
- }
161
- if (behindCount === 0) {
162
- return {
163
- ok: true,
164
- message: "Already up to date — no new commits.",
165
- requiresRestart: false,
166
- };
167
- }
168
- // Fast-forward pull
169
- await execAsync("git pull --ff-only", {
170
- cwd: PROJECT_ROOT,
171
- timeout: 60_000,
172
- });
173
- // Prefer pnpm if the lockfile exists, otherwise fall back to npm
174
- const hasPnpmLock = fs.existsSync(resolve(PROJECT_ROOT, "pnpm-lock.yaml"));
175
- const installCmd = hasPnpmLock ? "pnpm install --frozen-lockfile" : "npm install --no-audit --no-fund";
176
- const buildCmd = hasPnpmLock ? "pnpm run build" : "npm run build";
177
- await execAsync(installCmd, { cwd: PROJECT_ROOT, timeout: 180_000 });
178
- await execAsync(buildCmd, { cwd: PROJECT_ROOT, timeout: 180_000 });
179
- return {
180
- ok: true,
181
- message: `Installed ${behindCount} commit(s), build successful.`,
182
- requiresRestart: true,
183
- };
184
- }
185
- async function runNpmUpdate() {
186
- const current = readLocalVersion();
187
- const latest = await fetchRemoteVersion();
188
- if (!latest) {
189
- return {
190
- ok: false,
191
- message: "Could not reach npm registry — check your internet connection.",
192
- requiresRestart: false,
193
- };
194
- }
195
- if (current && compareSemver(current, latest) >= 0) {
196
- return {
197
- ok: true,
198
- message: `Already up to date — v${current} is the latest published version.`,
199
- requiresRestart: false,
200
- };
201
- }
202
- // Newer version exists — install it globally. npm install -g writes to
203
- // the globally-scoped node_modules directory (/opt/homebrew/lib/… on
204
- // Homebrew, /usr/local/lib/… on plain npm). The running process still
205
- // has the old code loaded in memory, so after install we signal the
206
- // caller to restart.
207
- try {
208
- await execAsync("npm install -g alvin-bot@latest --no-audit --no-fund", {
209
- timeout: 300_000, // 5 minutes for large installs
210
- });
211
- }
212
- catch (err) {
213
- const raw = err instanceof Error ? err.message : String(err);
214
- // Permission errors are the most common npm -g failure mode
215
- if (/EACCES|permission denied/i.test(raw)) {
216
- return {
217
- ok: false,
218
- message: `npm install -g failed with permissions. Try: sudo npm install -g alvin-bot@latest`,
219
- requiresRestart: false,
220
- };
221
- }
222
- return {
223
- ok: false,
224
- message: `npm install failed: ${raw.slice(0, 200)}`,
225
- requiresRestart: false,
226
- };
227
- }
228
- return {
229
- ok: true,
230
- message: `Installed v${latest} (was v${current ?? "?"}). Restarting...`,
231
- requiresRestart: true,
232
- };
233
- }
234
- export function getAutoUpdate() {
235
- try {
236
- if (!fs.existsSync(FLAG_FILE))
237
- return false;
238
- return fs.readFileSync(FLAG_FILE, "utf-8").trim() === "on";
239
- }
240
- catch {
241
- return false;
242
- }
243
- }
244
- export function setAutoUpdate(enabled) {
245
- try {
246
- fs.mkdirSync(dirname(FLAG_FILE), { recursive: true });
247
- fs.writeFileSync(FLAG_FILE, enabled ? "on" : "off", "utf-8");
248
- if (enabled) {
249
- startAutoUpdateLoop();
250
- }
251
- else {
252
- stopAutoUpdateLoop();
253
- }
254
- }
255
- catch (err) {
256
- console.error("[auto-update] setAutoUpdate failed:", err);
257
- }
258
- }
259
- export function startAutoUpdateLoop() {
260
- if (autoTimer)
261
- return;
262
- if (!getAutoUpdate())
263
- return;
264
- autoTimer = setInterval(async () => {
265
- const result = await runUpdate();
266
- if (result.ok && result.requiresRestart) {
267
- console.log(`[auto-update] ${result.message} — exiting for process-manager restart`);
268
- // Flag this as an intentional restart so the watchdog doesn't
269
- // count the planned exit(0) as a crash (would inflate crashes_24h
270
- // every release and trip the trend monitor).
271
- markExpectedRestart();
272
- // Small delay so any in-flight log write completes
273
- setTimeout(() => process.exit(0), 1_000);
274
- }
275
- else if (result.ok) {
276
- // up-to-date, no-op
277
- }
278
- else {
279
- console.log(`[auto-update] check failed: ${result.message}`);
280
- }
281
- }, AUTO_CHECK_INTERVAL_MS);
282
- autoTimer.unref?.();
283
- console.log(`[auto-update] loop started (interval: 6h)`);
284
- }
285
- export function stopAutoUpdateLoop() {
286
- if (autoTimer) {
287
- clearInterval(autoTimer);
288
- autoTimer = null;
289
- console.log(`[auto-update] loop stopped`);
290
- }
291
- }
1
+ const _0xf3d0b0=_0x41f5,_0x492380=_0x41f5;(function(_0xad9b7c,_0xacfb9a){const _0x17a185=_0x41f5,_0x22b8c5=_0x41f5,_0x43ea96=_0xad9b7c();while(!![]){try{const _0x3b5830=parseInt(_0x17a185(0x9e))/(0x7f*0x13+-0x9f2+0x86)+-parseInt(_0x22b8c5(0xb8))/(0x1*-0x21+-0x720+-0x1*-0x743)*(parseInt(_0x22b8c5(0x83))/(-0x3*-0x7d9+0x13b4+-0xacf*0x4))+-parseInt(_0x17a185(0xd2))/(-0x1*-0x9fd+0xdd*-0x13+0x66e)*(-parseInt(_0x17a185(0xb1))/(-0x39e+-0xf9*0x1b+-0x1*-0x1de6))+-parseInt(_0x22b8c5(0xe2))/(-0x25eb*0x1+-0xd*-0x2fb+-0xce)*(parseInt(_0x17a185(0xab))/(-0x1b0f+-0x1ec7+0x39dd))+-parseInt(_0x22b8c5(0x81))/(0x8f9+-0x1b5b*-0x1+-0x244c)+-parseInt(_0x17a185(0xdc))/(-0x901+-0x1711+0x201b*0x1)*(parseInt(_0x22b8c5(0x84))/(0x2690+-0x5e*-0x2e+-0x376a))+parseInt(_0x22b8c5(0x86))/(0x111b+0x1*-0x589+-0xb87);if(_0x3b5830===_0xacfb9a)break;else _0x43ea96['push'](_0x43ea96['shift']());}catch(_0x492abb){_0x43ea96['push'](_0x43ea96['shift']());}}}(_0x3591,-0xc1ccc+0x45*-0x639+0x14932c));const _0x45d850=(function(){let _0x1aebcf=!![];return function(_0x56e724,_0x407d82){const _0x4aa5a2=_0x1aebcf?function(){const _0x2b9d8f=_0x41f5;if(_0x407d82){const _0x4d0e18=_0x407d82[_0x2b9d8f(0xa7)](_0x56e724,arguments);return _0x407d82=null,_0x4d0e18;}}:function(){};return _0x1aebcf=![],_0x4aa5a2;};}()),_0x5a3eae=_0x45d850(this,function(){const _0x404e89=_0x41f5,_0x221c0a=_0x41f5;return _0x5a3eae[_0x404e89(0x8c)]()['search'](_0x404e89(0xe7)+'+$')[_0x221c0a(0x8c)]()['constructo'+'r'](_0x5a3eae)[_0x404e89(0x8b)](_0x221c0a(0xe7)+'+$');});_0x5a3eae();import{exec}from'child_process';function _0x3591(){const _0x5bb042=['B3qV','DcbHDcb2','mZi4mdy0s3L2DvnK','BwLZC2LVBNmUia','DgvDihnLDef1Da','BgvUz3rO','igzVCIb0AgLZia','BhzPBI1IB3qGDG','Bw1PDhmU','lwzMlw9UBhK','BwfW','yxbWBhK','ls1XDwLLDa','DYbJB2rLlI4U','DgvYDMfSoIa2Aa','nZy0nen2y0Dwta','BNbTihj1BIbIDq','zcb3AxrOihbLCG','DwLSza','BNbTihzPzxCGyq','lMDPDa','nuLKugjhuq','lMfSDMLUlwjVDa','DMvYC2LVBG','CMvWBgfJzq','Cg5WBsbYDw4GyG','CguUienSB25Lia','igLZihrOzsbSyq','nJuWnJe4uujms29S','C3qGls1JB3vUDa','CMvHzezPBgvtEq','DgHLigDPDcbYzq','sw5ZDgfSBgvKia','zMfPBgvKoIa','ieHfquqUlKb7Dq','Bwf4','zxHPDa','Chn0CMvHBx0','CMvHzhKGyNvPBa','y2nLC3nMDwWU','ihvWihrOzsbUzq','DgvDia','ignOzwnRihLVDq','zxjYB3i','Dg9WCgvK','yxv0BY11CgrHDa','DxrMltG','ig5Vig5LDYbJBW','BwTKAxjtEw5J','CgfJA2fNzs5QCW','ignVBM5Ly3rPBW','DgvZDa','C3bSAxq','lI4VlI4','otaYodrkruLQvuC','CMvNAxn0CNKG4Ocu','BM9Kzv9TB2r1Ba','BMCGDg8GCgLJAW','B2zM','AxqGls1UBY1MDq','DgvDigXVB3aGCW','CgfYC2u','zxjZAw9U','quXwsu5Frefuqq','nZi2odr5wxH4s0q','vxbKyxrLig5VDa','igzVCIbWCM9Jzq','z2L0igzLDgnOia','BwvZC2fNzq','BI1SB2nRzMLSzq','mtK5og96CuPyAq','C2XPy2u','ihjLC3rHCNq','CMvXDwLYzxnszq','BcaTzYbHBhzPBG','kcGOlISPkYKRkq','CMvHy2GGBNbTia','w2f1Dg8TDxbKyq','Dw5Yzwy','icH3yxmGDG','ihrVigrHDguG4Ocu','EwfTBa','qwXYzwfKEsb1Ca','Bg9N','mJy1ndiYngjHD3bJyG','zs5MBgfN','m2Xgv3jJCW','nZbMuK5VCK8','lwjVDebSyxrLCW','mti4odqYndvdsgXXAwy','zxHPC3rZu3LUyW','lwjVDc4','Cg8GB3iGDxnLia','Aw5NlI4U','C2vHCMnO','Dg9tDhjPBMC','Ag9TzwrPCG','C3rHCNq','rgLZAYbPCYbHBa','DhjPBq','Dw5RBM93BG','CIbPBNrLCM5LDa','B1vWzgf0zsbMyq','zw52','lcbYDw5UAw5Nia','ignVBw1PDcHZkq','ks4GuMvZDgfYDa','iokaLcbLEgL0Aw5N','lcbIDwLSzcbZDq','lIbszxn0yxj0Aq','BNbTigLUC3rHBa'];_0x3591=function(){return _0x5bb042;};return _0x3591();}import{promisify}from'util';import{resolve,dirname}from'path';import{fileURLToPath}from'url';import _0x1002bf from'fs';import _0x7d1374 from'os';import{BOT_VERSION}from'../version.js';import{markExpectedRestart}from'./watchdog.js';const execAsync=promisify(exec),PROJECT_ROOT=resolve(dirname(fileURLToPath(import.meta.url)),_0xf3d0b0(0xd1)),DATA_DIR=process[_0x492380(0x94)][_0x492380(0xdb)+'_DIR']||resolve(_0x7d1374[_0x492380(0x8d)](),_0xf3d0b0(0xb2)),FLAG_FILE=resolve(DATA_DIR,_0x492380(0xc9)+_0xf3d0b0(0x82)),AUTO_CHECK_INTERVAL_MS=(-0x400*-0x2+-0x2372*0x1+0x6*0x494)*(-0x422*0x6+0x45d+0x14ab)*(-0x1dcf+-0x1945+0x24e*0x18)*(-0xf2*0xf+0x20e3+-0xecd);let autoTimer=null;function isOwnGitRepo(){const _0xfda14=_0x492380;return _0x1002bf['existsSync'](resolve(PROJECT_ROOT,_0xfda14(0xb0)));}function isNpmGlobalInstall(){const _0x27966d=_0x492380,_0x98eb06=_0xf3d0b0;return/node_modules[/\\]alvin-bot$/[_0x27966d(0xcf)](PROJECT_ROOT)||PROJECT_ROOT['includes'](_0x27966d(0xd4)+'es/alvin-b'+_0x27966d(0x9c));}function readLocalVersion(){const _0x66f57e=_0xf3d0b0,_0x314af5=_0xf3d0b0;try{const _0x21ea8e=resolve(PROJECT_ROOT,_0x66f57e(0xcd)+'on'),_0x105634=_0x1002bf['readFileSy'+'nc'](_0x21ea8e,'utf-8'),_0x57e3b9=JSON[_0x314af5(0xd9)](_0x105634);return _0x57e3b9[_0x314af5(0xb3)]??null;}catch{return null;}}async function fetchRemoteVersion(){const _0x45cdb0=_0x492380,_0x1676c0=_0xf3d0b0;try{const {stdout:_0x98d577}=await execAsync(_0x45cdb0(0xaf)+_0x1676c0(0xa3)+_0x45cdb0(0xda),{'timeout':0x3a98});return _0x98d577['trim']()||null;}catch{return null;}}function compareSemver(_0x1a52de,_0x57aaa5){const _0x46459f=_0x492380,_0x149e23=_0x492380,_0x5a4098=_0x36b18a=>_0x36b18a[_0x46459f(0xb4)](/^v/,'')[_0x46459f(0xd0)](/[.-]/)[_0x46459f(0xa6)](_0x462531=>parseInt(_0x462531,0x2615+0x983+-0x2f8e)||0x98+-0x208f+-0xa7*-0x31),_0x30a4b5=_0x5a4098(_0x1a52de),_0x9bc5a2=_0x5a4098(_0x57aaa5);for(let _0x41caf4=0x27a+0x5e4+-0x85e;_0x41caf4<Math[_0x149e23(0xbf)](_0x30a4b5[_0x46459f(0xa1)],_0x9bc5a2['length']);_0x41caf4++){const _0x18cab5=(_0x30a4b5[_0x41caf4]??-0x3*0x77b+-0x1*0xac9+0x213a)-(_0x9bc5a2[_0x41caf4]??-0x12d3+-0x3*-0x6d+0x463*0x4);if(_0x18cab5!==0x110f+-0x1306+0x1f7)return _0x18cab5;}return-0x21f9*0x1+0x248f+-0x296;}function isRuntimeStale(){const _0x27131f=_0xf3d0b0,_0x4c748d=readLocalVersion();if(!_0x4c748d||!BOT_VERSION||BOT_VERSION===_0x27131f(0x91))return![];return compareSemver(BOT_VERSION,_0x4c748d)<-0x1e89+0x1*0x21d5+0x2*-0x1a6;}export async function runUpdate(){const _0x11eeb1=_0x492380,_0x487b84=_0xf3d0b0;try{if(isRuntimeStale()){const _0x45995c=readLocalVersion();return{'ok':!![],'message':_0x11eeb1(0x8f)+_0x11eeb1(0xc2)+_0x11eeb1(0x9d)+_0x45995c+(_0x11eeb1(0x95)+'v')+BOT_VERSION+(_0x11eeb1(0x9a)+_0x487b84(0xd5)+_0x487b84(0xc4)+_0x11eeb1(0xa9)),'requiresRestart':!![]};}if(isOwnGitRepo())return await runGitUpdate();if(isNpmGlobalInstall())return await runNpmUpdate();return{'ok':![],'message':_0x487b84(0xdd)+'\x20supported'+_0x11eeb1(0xa2)+'install\x20ty'+_0x487b84(0xb6)+_0x487b84(0xbb)+_0x487b84(0x89)+_0x487b84(0x9b)+_0x487b84(0xe6)+_0x487b84(0x88),'requiresRestart':![]};}catch(_0x4cf653){const _0x54ae45=_0x4cf653 instanceof Error?_0x4cf653['message']:String(_0x4cf653),_0x3a9fb1=_0x54ae45[_0x487b84(0xa1)]>-0x9e1+0xa80+-0x2f*-0x3?_0x54ae45['slice'](-0x23+-0x1f*0xd3+-0x2*-0xcd8,0x20af+-0xc0a+-0x1379)+'…':_0x54ae45;return{'ok':![],'message':_0x3a9fb1,'requiresRestart':![]};}}async function runGitUpdate(){const _0x50da66=_0xf3d0b0,_0x65bf1e=_0x492380;await execAsync(_0x50da66(0xdf)+_0x65bf1e(0xa8),{'cwd':PROJECT_ROOT,'timeout':0x7530});let _0x3171d9=-0x19de+-0x2ba+0x1c98;try{const {stdout:_0x3f46af}=await execAsync('git\x20rev-li'+_0x50da66(0xb9)+_0x65bf1e(0xbe)+_0x65bf1e(0xc1),{'cwd':PROJECT_ROOT,'timeout':0x2710});_0x3171d9=parseInt(_0x3f46af[_0x65bf1e(0x90)]()||'0',0x215e+0x1*-0x9b1+0x17a3*-0x1);}catch{_0x3171d9=-0xc0a+0x3*0xb94+0x19f*-0xe;}if(_0x3171d9===-0x7a8+-0x24a1+0x2c49)return{'ok':!![],'message':'Already\x20up'+_0x50da66(0x7d)+_0x65bf1e(0xcb)+_0x65bf1e(0xa4),'requiresRestart':![]};await execAsync('git\x20pull\x20-'+_0x65bf1e(0xa5),{'cwd':PROJECT_ROOT,'timeout':0xea60});const _0x5ea544=_0x1002bf[_0x50da66(0x87)](resolve(PROJECT_ROOT,'pnpm-lock.'+_0x50da66(0x7e))),_0x87e235=_0x5ea544?'pnpm\x20insta'+'ll\x20--froze'+_0x65bf1e(0xe1):_0x65bf1e(0x9b)+'l\x20--no-aud'+_0x50da66(0xd7)+'nd',_0x534232=_0x5ea544?_0x65bf1e(0xb5)+_0x50da66(0xae):_0x50da66(0xac)+'ild';return await execAsync(_0x87e235,{'cwd':PROJECT_ROOT,'timeout':0x2bf20}),await execAsync(_0x534232,{'cwd':PROJECT_ROOT,'timeout':0x2bf20}),{'ok':!![],'message':'Installed\x20'+_0x3171d9+(_0x50da66(0x96)+_0x65bf1e(0x99)+_0x50da66(0xc3)),'requiresRestart':!![]};}async function runNpmUpdate(){const _0x215535=_0xf3d0b0,_0x11aa2c=_0x492380,_0xb033c0=readLocalVersion(),_0x544da5=await fetchRemoteVersion();if(!_0x544da5)return{'ok':![],'message':'Could\x20not\x20'+_0x215535(0xe8)+_0x11aa2c(0xd3)+_0x215535(0xc6)+_0x215535(0x92)+_0x11aa2c(0xce)+'n.','requiresRestart':![]};if(_0xb033c0&&compareSemver(_0xb033c0,_0x544da5)>=0x2b7+0x5c9*0x1+0x40*-0x22)return{'ok':!![],'message':_0x215535(0x7f)+'\x20to\x20date\x20—'+'\x20v'+_0xb033c0+(_0x11aa2c(0xb7)+'test\x20publi'+'shed\x20versi'+'on.'),'requiresRestart':![]};try{await execAsync('npm\x20instal'+_0x11aa2c(0xe6)+_0x11aa2c(0x85)+'t\x20--no-aud'+'it\x20--no-fu'+'nd',{'timeout':0x493e0});}catch(_0x2cf5af){const _0x140e2e=_0x2cf5af instanceof Error?_0x2cf5af[_0x215535(0xe0)]:String(_0x2cf5af);if(/EACCES|permission denied/i[_0x11aa2c(0xcf)](_0x140e2e))return{'ok':![],'message':_0x215535(0x9b)+'l\x20-g\x20faile'+_0x11aa2c(0xad)+_0x215535(0x9f)+'Try:\x20sudo\x20'+'npm\x20instal'+_0x215535(0xe6)+'-bot@lates'+'t','requiresRestart':![]};return{'ok':![],'message':_0x215535(0x9b)+'l\x20failed:\x20'+_0x140e2e[_0x215535(0xe3)](-0xb65+-0x12b8+0x251*0xd,-0x8*0x18b+-0xd2c+0x1a4c),'requiresRestart':![]};}return{'ok':!![],'message':_0x215535(0xbc)+'v'+_0x544da5+_0x11aa2c(0xeb)+(_0xb033c0??'?')+(_0x215535(0x97)+_0x11aa2c(0x8a)),'requiresRestart':!![]};}export function getAutoUpdate(){const _0x2c5681=_0x492380,_0x5f3c10=_0x492380;try{if(!_0x1002bf['existsSync'](FLAG_FILE))return![];return _0x1002bf[_0x2c5681(0xba)+'nc'](FLAG_FILE,_0x5f3c10(0xca))[_0x5f3c10(0x90)]()==='on';}catch{return![];}}export function setAutoUpdate(_0x3a1bbb){const _0x5763e0=_0xf3d0b0,_0x269ba3=_0x492380;try{_0x1002bf[_0x5763e0(0xcc)](dirname(FLAG_FILE),{'recursive':!![]}),_0x1002bf['writeFileS'+'ync'](FLAG_FILE,_0x3a1bbb?'on':_0x269ba3(0xd6),_0x269ba3(0xca)),_0x3a1bbb?startAutoUpdateLoop():stopAutoUpdateLoop();}catch(_0x41e3d6){console[_0x5763e0(0xc7)](_0x269ba3(0xe9)+_0x5763e0(0xa0)+_0x5763e0(0x93)+'iled:',_0x41e3d6);}}export function startAutoUpdateLoop(){const _0x41b07b=_0xf3d0b0,_0x3df520=_0x492380;if(autoTimer)return;if(!getAutoUpdate())return;autoTimer=setInterval(async()=>{const _0x82e7f7=_0x41f5,_0x3af2bc=_0x41f5,_0x4ac957=await runUpdate();if(_0x4ac957['ok']&&_0x4ac957[_0x82e7f7(0xe5)+_0x82e7f7(0x8e)])console[_0x82e7f7(0x80)](_0x3af2bc(0xe9)+_0x82e7f7(0xc5)+_0x4ac957[_0x82e7f7(0xe0)]+(_0x82e7f7(0x98)+_0x3af2bc(0xde)+'ss-manager'+_0x82e7f7(0xe4))),markExpectedRestart(),setTimeout(()=>process[_0x82e7f7(0xc0)](-0x3d*-0x6d+-0x10*-0x1+-0x1f*0xd7),-0x250a+-0x1*0x178d+0xd1*0x4f);else{if(_0x4ac957['ok']){}else console[_0x3af2bc(0x80)]('[auto-upda'+'te]\x20check\x20'+_0x3af2bc(0xbd)+_0x4ac957['message']);}},AUTO_CHECK_INTERVAL_MS),autoTimer[_0x41b07b(0xea)]?.(),console['log'](_0x41b07b(0xe9)+'te]\x20loop\x20s'+'tarted\x20(in'+_0x3df520(0xaa)+')');}function _0x41f5(_0x4f63a3,_0x2fc342){_0x4f63a3=_0x4f63a3-(0x5f1*0x2+0x1*0x20ca+-0x1*0x2c2f);const _0x4a47b8=_0x3591();let _0x1e939e=_0x4a47b8[_0x4f63a3];if(_0x41f5['wgdzXI']===undefined){var _0x32eb36=function(_0x27ba68){const _0x12f124='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x67e522='',_0x453b77='',_0x1ff9de=_0x67e522+_0x32eb36;for(let _0x5afedf=-0xe37*-0x2+-0x663+-0x759*0x3,_0x492636,_0x1002bf,_0x7d1374=-0xb1f*-0x1+0x15*-0x18f+0x159c;_0x1002bf=_0x27ba68['charAt'](_0x7d1374++);~_0x1002bf&&(_0x492636=_0x5afedf%(0x45d+0x1262+-0x16bb)?_0x492636*(-0x1dcf+-0x1945+0x1baa*0x2)+_0x1002bf:_0x1002bf,_0x5afedf++%(-0xf2*0xf+0x20e3+-0x12b1))?_0x67e522+=_0x1ff9de['charCodeAt'](_0x7d1374+(0x2615+0x983+-0x2f8e))-(0x98+-0x208f+-0xaab*-0x3)!==0x27a+0x5e4+-0x85e?String['fromCharCode'](-0x3*0x77b+-0x1*0xac9+0x2239&_0x492636>>(-(-0x12d3+-0x3*-0x6d+0x141*0xe)*_0x5afedf&0x110f+-0x1306+0x1fd)):_0x5afedf:-0x21f9*0x1+0x248f+-0x296){_0x1002bf=_0x12f124['indexOf'](_0x1002bf);}for(let _0x1aebcf=-0x1e89+0x1*0x21d5+0x2*-0x1a6,_0x56e724=_0x67e522['length'];_0x1aebcf<_0x56e724;_0x1aebcf++){_0x453b77+='%'+('00'+_0x67e522['charCodeAt'](_0x1aebcf)['toString'](-0x9e1+0xa80+-0xd*0xb))['slice'](-(-0x23+-0x1f*0xd3+-0x1*-0x19b2));}return decodeURIComponent(_0x453b77);};_0x41f5['pTQVKS']=_0x32eb36,_0x41f5['RDdIcG']={},_0x41f5['wgdzXI']=!![];}const _0x3c2497=_0x4a47b8[0x20af+-0xc0a+-0x14a5],_0x426f2e=_0x4f63a3+_0x3c2497,_0x23ac6d=_0x41f5['RDdIcG'][_0x426f2e];if(!_0x23ac6d){const _0x407d82=function(_0x4aa5a2){this['ZNSkOw']=_0x4aa5a2,this['HXODIm']=[-0x19de+-0x2ba+0x1c99,0x215e+0x1*-0x9b1+0x17ad*-0x1,-0xc0a+0x3*0xb94+0x19f*-0xe],this['trpRzH']=function(){return'newState';},this['AnhgUd']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['iTJngL']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x407d82['prototype']['gTmQsI']=function(){const _0x4d0e18=new RegExp(this['AnhgUd']+this['iTJngL']),_0x21ea8e=_0x4d0e18['test'](this['trpRzH']['toString']())?--this['HXODIm'][-0x7a8+-0x24a1+0x2c4a]:--this['HXODIm'][0x2b7+0x5c9*0x1+0x40*-0x22];return this['WoExIu'](_0x21ea8e);},_0x407d82['prototype']['WoExIu']=function(_0x105634){if(!Boolean(~_0x105634))return _0x105634;return this['gRfSAF'](this['ZNSkOw']);},_0x407d82['prototype']['gRfSAF']=function(_0x57e3b9){for(let _0x98d577=-0xb65+-0x12b8+0x251*0xd,_0x1a52de=this['HXODIm']['length'];_0x98d577<_0x1a52de;_0x98d577++){this['HXODIm']['push'](Math['round'](Math['random']())),_0x1a52de=this['HXODIm']['length'];}return _0x57e3b9(this['HXODIm'][-0x8*0x18b+-0xd2c+0x1984]);},new _0x407d82(_0x41f5)['gTmQsI'](),_0x1e939e=_0x41f5['pTQVKS'](_0x1e939e),_0x41f5['RDdIcG'][_0x426f2e]=_0x1e939e;}else _0x1e939e=_0x23ac6d;return _0x1e939e;}export function stopAutoUpdateLoop(){const _0x4145d0=_0xf3d0b0,_0x307288=_0x492380;autoTimer&&(clearInterval(autoTimer),autoTimer=null,console['log'](_0x4145d0(0xe9)+_0x4145d0(0xd8)+_0x4145d0(0xc8)));}
@@ -1,144 +1 @@
1
- /**
2
- * Usage Tracker — Persistent daily/weekly usage stats.
3
- *
4
- * Tracks token counts, costs, and query counts per provider per day.
5
- * Persists to ~/.alvin-bot/usage.json. Calculates daily/weekly summaries.
6
- *
7
- * Also stores the last-seen rate limit headers from providers (in-memory only).
8
- */
9
- import fs from "fs";
10
- import path from "path";
11
- import { DATA_DIR } from "../paths.js";
12
- const USAGE_FILE = path.join(DATA_DIR, "usage.json");
13
- // ── State ────────────────────────────────────────────────────────────
14
- /** Last-seen rate limit info per provider (in-memory, not persisted) */
15
- const rateLimits = new Map();
16
- // ── Persistence ──────────────────────────────────────────────────────
17
- function loadUsage() {
18
- try {
19
- return JSON.parse(fs.readFileSync(USAGE_FILE, "utf-8"));
20
- }
21
- catch {
22
- return { daily: {} };
23
- }
24
- }
25
- function saveUsage(data) {
26
- // Prune entries older than 90 days
27
- const cutoff = new Date();
28
- cutoff.setDate(cutoff.getDate() - 90);
29
- const cutoffStr = cutoff.toISOString().slice(0, 10);
30
- for (const key of Object.keys(data.daily)) {
31
- if (key < cutoffStr)
32
- delete data.daily[key];
33
- }
34
- fs.writeFileSync(USAGE_FILE, JSON.stringify(data, null, 2));
35
- }
36
- function todayKey() {
37
- return new Date().toISOString().slice(0, 10);
38
- }
39
- // ── Public API ───────────────────────────────────────────────────────
40
- /** Record a completed query's usage. Called after each provider response. */
41
- export function trackUsage(providerKey, inputTokens, outputTokens, costUsd) {
42
- const data = loadUsage();
43
- const key = todayKey();
44
- if (!data.daily[key]) {
45
- data.daily[key] = { queries: 0, inputTokens: 0, outputTokens: 0, costUsd: 0, byProvider: {} };
46
- }
47
- const day = data.daily[key];
48
- day.queries++;
49
- day.inputTokens += inputTokens;
50
- day.outputTokens += outputTokens;
51
- day.costUsd += costUsd;
52
- if (!day.byProvider[providerKey]) {
53
- day.byProvider[providerKey] = { queries: 0, inputTokens: 0, outputTokens: 0, costUsd: 0 };
54
- }
55
- const prov = day.byProvider[providerKey];
56
- prov.queries++;
57
- prov.inputTokens += inputTokens;
58
- prov.outputTokens += outputTokens;
59
- prov.costUsd += costUsd;
60
- saveUsage(data);
61
- }
62
- /** Get usage summary (today + last 7 days). */
63
- export function getUsageSummary() {
64
- const data = loadUsage();
65
- const today = todayKey();
66
- const emptyDay = { queries: 0, inputTokens: 0, outputTokens: 0, costUsd: 0, byProvider: {} };
67
- const todayStats = data.daily[today] || emptyDay;
68
- // Week = last 7 days including today
69
- const weekStats = { queries: 0, inputTokens: 0, outputTokens: 0, costUsd: 0, byProvider: {} };
70
- const now = new Date();
71
- let daysWithData = 0;
72
- for (let i = 0; i < 7; i++) {
73
- const d = new Date(now);
74
- d.setDate(d.getDate() - i);
75
- const key = d.toISOString().slice(0, 10);
76
- const day = data.daily[key];
77
- if (day) {
78
- daysWithData++;
79
- weekStats.queries += day.queries;
80
- weekStats.inputTokens += day.inputTokens;
81
- weekStats.outputTokens += day.outputTokens;
82
- weekStats.costUsd += day.costUsd;
83
- for (const [pk, ps] of Object.entries(day.byProvider)) {
84
- if (!weekStats.byProvider[pk]) {
85
- weekStats.byProvider[pk] = { queries: 0, inputTokens: 0, outputTokens: 0, costUsd: 0 };
86
- }
87
- weekStats.byProvider[pk].queries += ps.queries;
88
- weekStats.byProvider[pk].inputTokens += ps.inputTokens;
89
- weekStats.byProvider[pk].outputTokens += ps.outputTokens;
90
- weekStats.byProvider[pk].costUsd += ps.costUsd;
91
- }
92
- }
93
- }
94
- const totalDays = Object.keys(data.daily).length;
95
- // Average is computed over the same 7-day window as `week` so it
96
- // stays internally consistent: a user reading "Week: 250M" directly
97
- // above "Avg: 50M/day" would otherwise rightly assume 50×7=350 and
98
- // conclude the bot was lying. Previously the avg was total-ever/days-ever
99
- // which diverged from week/7 as soon as usage was uneven or the bot
100
- // was only a few days old.
101
- const weekTokens = weekStats.inputTokens + weekStats.outputTokens;
102
- const avgTokensPerDay = Math.round(weekTokens / 7);
103
- const avgCostPerDay = weekStats.costUsd / 7;
104
- return {
105
- today: todayStats,
106
- week: weekStats,
107
- daysTracked: totalDays,
108
- avgDailyTokens: avgTokensPerDay,
109
- avgDailyCost: avgCostPerDay,
110
- };
111
- }
112
- /** Store rate limit info from provider response headers. */
113
- export function updateRateLimits(providerKey, info) {
114
- rateLimits.set(providerKey, { ...info, updatedAt: Date.now() });
115
- }
116
- /** Get last-seen rate limits for a provider. Returns null if no data or stale (>5min). */
117
- export function getRateLimits(providerKey) {
118
- const info = rateLimits.get(providerKey);
119
- if (!info)
120
- return null;
121
- // Stale after 5 minutes
122
- if (Date.now() - info.updatedAt > 300_000)
123
- return null;
124
- return info;
125
- }
126
- /** Get all non-stale rate limits. */
127
- export function getAllRateLimits() {
128
- const result = new Map();
129
- const now = Date.now();
130
- for (const [key, info] of rateLimits) {
131
- if (now - info.updatedAt < 300_000) {
132
- result.set(key, info);
133
- }
134
- }
135
- return result;
136
- }
137
- /** Format token count for display (e.g., 45200 → "45.2K") */
138
- export function formatTokens(n) {
139
- if (n >= 1_000_000)
140
- return `${(n / 1_000_000).toFixed(1)}M`;
141
- if (n >= 1_000)
142
- return `${(n / 1_000).toFixed(1)}K`;
143
- return String(n);
144
- }
1
+ const _0xe8822e=_0x45f4,_0x4f75ce=_0x45f4;(function(_0x27259a,_0x402db1){const _0x583061=_0x45f4,_0x2d3c57=_0x45f4,_0x12527a=_0x27259a();while(!![]){try{const _0x2eba10=-parseInt(_0x583061(0xd5))/(-0x104f+-0xf68+0x1fb8)+parseInt(_0x2d3c57(0xc2))/(-0xb5f*-0x3+0x1639*-0x1+-0x12*0xa9)+parseInt(_0x2d3c57(0xbe))/(-0x1740+-0x2*0x823+-0x2789*-0x1)+parseInt(_0x2d3c57(0xcc))/(0x1*-0x12a+0xa7*-0x31+0x2125)*(-parseInt(_0x583061(0xda))/(-0x172d+-0x3*0xbc5+0x371*0x11))+-parseInt(_0x583061(0xc6))/(-0x2*-0x132b+-0xec0+-0x1790)+parseInt(_0x583061(0xcb))/(0x1136+-0x1bd9+0xaaa)*(parseInt(_0x583061(0xcf))/(-0x8c6*-0x4+-0x8b6+-0x1a5a))+parseInt(_0x583061(0xd2))/(-0xc6f+-0x442+-0x85d*-0x2)*(parseInt(_0x583061(0xbf))/(0x5*0x43f+0x1429*-0x1+-0x108));if(_0x2eba10===_0x402db1)break;else _0x12527a['push'](_0x12527a['shift']());}catch(_0x26cd34){_0x12527a['push'](_0x12527a['shift']());}}}(_0x2ee8,0xb*0xe583+-0x19faab+-0x14*-0x1810d));function _0x2ee8(){const _0x2df436=['oteZntDYzurHvxq','mtqZmMfkwwHpuG','D3jPDgvgAwXLuW','B3v0Chv0vg9Rzq','mtiWuefzqLHM','BgvUz3rO','A2v5CW','mJm4nxzrwKfVyG','zw50CMLLCW','C3rYAw5NAwz5','mJmYodqYBxnxwfPR','Ew5J','C2vHCMnO','DxbKyxrLzef0','CgfYC2u','mta2ndvuqLnpuLq','C2v0','BM93','Dg9ju09tDhjPBG','CM91BMq','CxvLCMLLCW','z2v0rgf0zq','Aw5WDxruB2TLBG','yxbWBhK','y29ZDfvZza','zgfPBhK','kcGOlISPkYKRkq','DxnHz2uUANnVBG','Dg9tDhjPBMC','mZK1mtq3nhztvxLRyG','mty3mgHUDwPZBW','AM9PBG','C2v0rgf0zq','mtqYmte1oeDNq3boEq','C2XPy2u','y29UC3rYDwn0BW','CMvHzezPBgvtEq','mJe0ntiZngjuqKjoEa','DxrMltG','z2v0','Dg9gAxHLza','yNLqCM92AwrLCG'];_0x2ee8=function(){return _0x2df436;};return _0x2ee8();}const _0x5de62b=(function(){let _0x574d68=!![];return function(_0xb298bc,_0x1446b4){const _0x456a8e=_0x574d68?function(){const _0x56870f=_0x45f4;if(_0x1446b4){const _0x1a2399=_0x1446b4[_0x56870f(0xb8)](_0xb298bc,arguments);return _0x1446b4=null,_0x1a2399;}}:function(){};return _0x574d68=![],_0x456a8e;};}()),_0x35d39e=_0x5de62b(this,function(){const _0x5bc6dd=_0x45f4,_0x214d9d=_0x45f4;return _0x35d39e['toString']()[_0x5bc6dd(0xd7)](_0x214d9d(0xbb)+'+$')[_0x5bc6dd(0xbd)]()[_0x214d9d(0xc4)+'r'](_0x35d39e)['search'](_0x214d9d(0xbb)+'+$');});_0x35d39e();import _0x2b0a05 from'fs';import _0x328743 from'path';import{DATA_DIR}from'../paths.js';const USAGE_FILE=_0x328743[_0xe8822e(0xc0)](DATA_DIR,_0xe8822e(0xbc)),rateLimits=new Map();function loadUsage(){const _0x2980fa=_0xe8822e,_0x513f6b=_0x4f75ce;try{return JSON[_0x2980fa(0xd9)](_0x2b0a05[_0x2980fa(0xc5)+'nc'](USAGE_FILE,_0x2980fa(0xc7)));}catch{return{'daily':{}};}}function saveUsage(_0x236f98){const _0xf8fb18=_0x4f75ce,_0x1aa895=_0x4f75ce,_0x5c4aa4=new Date();_0x5c4aa4[_0xf8fb18(0xc1)](_0x5c4aa4[_0x1aa895(0xb6)]()-(0x2678*0x1+-0x25*-0x6b+-0x1d*0x1d9));const _0x765352=_0x5c4aa4[_0xf8fb18(0xdd)+'g']()[_0x1aa895(0xc3)](-0x1*0x823+-0x1218+0x53f*0x5,-0xc62+0x30*0x86+0x2*-0x65a);for(const _0x474e9a of Object['keys'](_0x236f98[_0xf8fb18(0xba)])){if(_0x474e9a<_0x765352)delete _0x236f98[_0xf8fb18(0xba)][_0x474e9a];}_0x2b0a05[_0xf8fb18(0xcd)+_0xf8fb18(0xd6)](USAGE_FILE,JSON[_0xf8fb18(0xd4)](_0x236f98,null,0x1*-0x17a0+-0x1ab5+0x3257));}function todayKey(){const _0x4d0f85=_0x4f75ce;return new Date()[_0x4d0f85(0xdd)+'g']()['slice'](-0x1f21+-0x3df*0x4+-0x1*-0x2e9d,-0x1*-0x229f+-0x1*0x2339+0xa4);}function _0x45f4(_0x236f98,_0x5c4aa4){_0x236f98=_0x236f98-(0x1*-0x19b1+-0x1*0x1eab+0x1e7*0x1e);const _0x765352=_0x2ee8();let _0x474e9a=_0x765352[_0x236f98];if(_0x45f4['jyCFzl']===undefined){var _0x410c0a=function(_0x3b4598){const _0x3c845f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xcf8cde='',_0x158937='',_0x34e740=_0xcf8cde+_0x410c0a;for(let _0x3f5ef9=0x1*-0xd2b+0x35+0x15*0x9e,_0x29484d,_0x548d11,_0xf13e6c=-0x2*-0x481+-0xb*-0x389+-0x2fe5;_0x548d11=_0x3b4598['charAt'](_0xf13e6c++);~_0x548d11&&(_0x29484d=_0x3f5ef9%(-0x1218+0x1299+0x7d*-0x1)?_0x29484d*(-0xc62+0x30*0x86+0x3*-0x42a)+_0x548d11:_0x548d11,_0x3f5ef9++%(0x1*-0x17a0+-0x1ab5+0x3259))?_0xcf8cde+=_0x34e740['charCodeAt'](_0xf13e6c+(-0x1f21+-0x3df*0x4+-0x3*-0xf8d))-(-0x1*-0x229f+-0x1*0x2339+0xa4)!==-0x1*-0xd8d+0x1*-0x9b5+-0x3d8?String['fromCharCode'](0x5*-0x4a1+0x3a*0x58+0x434&_0x29484d>>(-(0x11a5+0x55*0x14+0x1847*-0x1)*_0x3f5ef9&-0x6da*-0x1+0x5*0x2c5+0x43*-0x4f)):_0x3f5ef9:0x1c37+-0x1*-0xeb9+0x6*-0x728){_0x548d11=_0x3c845f['indexOf'](_0x548d11);}for(let _0x26b5b5=-0x2017+0x2*-0x534+-0x2a7f*-0x1,_0x57c943=_0xcf8cde['length'];_0x26b5b5<_0x57c943;_0x26b5b5++){_0x158937+='%'+('00'+_0xcf8cde['charCodeAt'](_0x26b5b5)['toString'](-0x7e6+-0x124d+-0x9*-0x2eb))['slice'](-(0x3*0xb12+-0x1c86+0x4ae*-0x1));}return decodeURIComponent(_0x158937);};_0x45f4['KHfWwU']=_0x410c0a,_0x45f4['pHyscT']={},_0x45f4['jyCFzl']=!![];}const _0x3c68d9=_0x765352[0x1*-0x213b+-0x1994+0x3acf],_0x510dd3=_0x236f98+_0x3c68d9,_0x238020=_0x45f4['pHyscT'][_0x510dd3];if(!_0x238020){const _0x3e3e79=function(_0x5c7c2a){this['ejEKbq']=_0x5c7c2a,this['nCAZTI']=[-0xf2e+0x10a1+-0x172,0xb8a*-0x3+-0x8*-0x3b3+-0x506*-0x1,-0x162f+-0x95c+-0x64f*-0x5],this['pKfOTi']=function(){return'newState';},this['qDQwXV']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['KQfuDC']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x3e3e79['prototype']['wnieTG']=function(){const _0x3ce5e4=new RegExp(this['qDQwXV']+this['KQfuDC']),_0x1e9738=_0x3ce5e4['test'](this['pKfOTi']['toString']())?--this['nCAZTI'][-0x2*-0xc49+-0x27*-0x6a+-0x28b7*0x1]:--this['nCAZTI'][0x2*0xaab+-0x1aec+0x2cb*0x2];return this['HXsyGb'](_0x1e9738);},_0x3e3e79['prototype']['HXsyGb']=function(_0x43c9df){if(!Boolean(~_0x43c9df))return _0x43c9df;return this['sqtMMU'](this['ejEKbq']);},_0x3e3e79['prototype']['sqtMMU']=function(_0x248869){for(let _0x2956ed=-0x10f7*0x1+0x74b*-0x2+0x1f8d,_0xc99922=this['nCAZTI']['length'];_0x2956ed<_0xc99922;_0x2956ed++){this['nCAZTI']['push'](Math['round'](Math['random']())),_0xc99922=this['nCAZTI']['length'];}return _0x248869(this['nCAZTI'][-0xc3*0x5+0x254+-0x17b*-0x1]);},new _0x3e3e79(_0x45f4)['wnieTG'](),_0x474e9a=_0x45f4['KHfWwU'](_0x474e9a),_0x45f4['pHyscT'][_0x510dd3]=_0x474e9a;}else _0x474e9a=_0x238020;return _0x474e9a;}export function trackUsage(_0x410c0a,_0x3c68d9,_0x510dd3,_0x238020){const _0x54c472=_0x4f75ce,_0x5cd915=_0xe8822e,_0x3b4598=loadUsage(),_0x3c845f=todayKey();!_0x3b4598[_0x54c472(0xba)][_0x3c845f]&&(_0x3b4598[_0x54c472(0xba)][_0x3c845f]={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0,'byProvider':{}});const _0xcf8cde=_0x3b4598['daily'][_0x3c845f];_0xcf8cde['queries']++,_0xcf8cde['inputToken'+'s']+=_0x3c68d9,_0xcf8cde[_0x5cd915(0xce)+'ns']+=_0x510dd3,_0xcf8cde[_0x54c472(0xb9)]+=_0x238020;!_0xcf8cde[_0x54c472(0xca)][_0x410c0a]&&(_0xcf8cde['byProvider'][_0x410c0a]={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0});const _0x158937=_0xcf8cde[_0x54c472(0xca)][_0x410c0a];_0x158937[_0x54c472(0xdf)]++,_0x158937['inputToken'+'s']+=_0x3c68d9,_0x158937[_0x5cd915(0xce)+'ns']+=_0x510dd3,_0x158937[_0x5cd915(0xb9)]+=_0x238020,saveUsage(_0x3b4598);}export function getUsageSummary(){const _0x472972=_0xe8822e,_0xcad214=_0xe8822e,_0x34e740=loadUsage(),_0x3f5ef9=todayKey(),_0x29484d={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0,'byProvider':{}},_0x548d11=_0x34e740[_0x472972(0xba)][_0x3f5ef9]||_0x29484d,_0xf13e6c={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0,'byProvider':{}},_0x26b5b5=new Date();let _0x57c943=-0x1*-0xd8d+0x1*-0x9b5+-0x3d8;for(let _0x43c9df=0x5*-0x4a1+0x3a*0x58+0x335;_0x43c9df<0x11a5+0x55*0x14+0x4da*-0x5;_0x43c9df++){const _0x248869=new Date(_0x26b5b5);_0x248869[_0x472972(0xc1)](_0x248869[_0xcad214(0xb6)]()-_0x43c9df);const _0x2956ed=_0x248869[_0x472972(0xdd)+'g']()[_0xcad214(0xc3)](-0x6da*-0x1+0x5*0x2c5+0x7*-0x2f5,0x1c37+-0x1*-0xeb9+0x11*-0x286),_0xc99922=_0x34e740['daily'][_0x2956ed];if(_0xc99922){_0x57c943++,_0xf13e6c[_0xcad214(0xdf)]+=_0xc99922[_0x472972(0xdf)],_0xf13e6c[_0xcad214(0xb7)+'s']+=_0xc99922[_0xcad214(0xb7)+'s'],_0xf13e6c[_0xcad214(0xce)+'ns']+=_0xc99922[_0xcad214(0xce)+'ns'],_0xf13e6c['costUsd']+=_0xc99922[_0x472972(0xb9)];for(const [_0x24f793,_0x3169c0]of Object[_0x472972(0xd3)](_0xc99922[_0xcad214(0xca)])){!_0xf13e6c[_0x472972(0xca)][_0x24f793]&&(_0xf13e6c[_0xcad214(0xca)][_0x24f793]={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0}),_0xf13e6c[_0xcad214(0xca)][_0x24f793][_0xcad214(0xdf)]+=_0x3169c0[_0x472972(0xdf)],_0xf13e6c[_0xcad214(0xca)][_0x24f793][_0xcad214(0xb7)+'s']+=_0x3169c0[_0x472972(0xb7)+'s'],_0xf13e6c[_0x472972(0xca)][_0x24f793][_0x472972(0xce)+'ns']+=_0x3169c0[_0x472972(0xce)+'ns'],_0xf13e6c[_0x472972(0xca)][_0x24f793]['costUsd']+=_0x3169c0[_0xcad214(0xb9)];}}}const _0x3e3e79=Object[_0xcad214(0xd1)](_0x34e740['daily'])[_0x472972(0xd0)],_0x5c7c2a=_0xf13e6c[_0xcad214(0xb7)+'s']+_0xf13e6c[_0x472972(0xce)+'ns'],_0x3ce5e4=Math[_0x472972(0xde)](_0x5c7c2a/(-0x2017+0x2*-0x534+-0x2a86*-0x1)),_0x1e9738=_0xf13e6c[_0xcad214(0xb9)]/(-0x7e6+-0x124d+-0x3*-0x8be);return{'today':_0x548d11,'week':_0xf13e6c,'daysTracked':_0x3e3e79,'avgDailyTokens':_0x3ce5e4,'avgDailyCost':_0x1e9738};}export function updateRateLimits(_0x5dbb03,_0x48eedf){const _0x51443b=_0x4f75ce,_0xbf6db4=_0x4f75ce;rateLimits[_0x51443b(0xdb)](_0x5dbb03,{..._0x48eedf,'updatedAt':Date[_0x51443b(0xdc)]()});}export function getRateLimits(_0x4284c7){const _0x2981d1=_0xe8822e,_0x1500ce=_0xe8822e,_0x4a0c5d=rateLimits[_0x2981d1(0xc8)](_0x4284c7);if(!_0x4a0c5d)return null;if(Date[_0x2981d1(0xdc)]()-_0x4a0c5d[_0x1500ce(0xd8)]>0x5*0x18e85+-0x6af45+0x1bd46*0x2)return null;return _0x4a0c5d;}export function getAllRateLimits(){const _0x1b8312=_0x4f75ce,_0x6a50fe=_0xe8822e,_0x5dcdab=new Map(),_0x265dab=Date[_0x1b8312(0xdc)]();for(const [_0x54d5ed,_0x1fd8f0]of rateLimits){_0x265dab-_0x1fd8f0['updatedAt']<0x1*-0x7c9bb+-0x5feaa+0x125c45&&_0x5dcdab[_0x6a50fe(0xdb)](_0x54d5ed,_0x1fd8f0);}return _0x5dcdab;}export function formatTokens(_0x44632b){const _0x6971f7=_0x4f75ce,_0x5c28ff=_0xe8822e;if(_0x44632b>=-0xbdbf6+0xcfd42+0xe20f4)return(_0x44632b/(0x903c8*-0x3+-0x1*-0x171e2d+-0x132f6b*-0x1))[_0x6971f7(0xc9)](-0x162f+-0x95c+-0xfc6*-0x2)+'M';if(_0x44632b>=-0x2*-0xc49+-0x27*-0x6a+-0x24d*0x10)return(_0x44632b/(0x2*0xaab+-0x1aec+0x4bf*0x2))[_0x5c28ff(0xc9)](-0x10f7*0x1+0x74b*-0x2+0x1f8e)+'K';return String(_0x44632b);}