alvin-bot 5.7.0 → 5.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +25 -31
  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 -174
  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 -583
  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 -86
  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 -1902
  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
+ function _0x7c07(_0xd7ea8a,_0x22d3ee){_0xd7ea8a=_0xd7ea8a-(-0x369+-0x1d*-0xc5+-0x61a*0x3);const _0x53f34f=_0x3207();let _0x361e4a=_0x53f34f[_0xd7ea8a];if(_0x7c07['LAoNfp']===undefined){var _0x1a255e=function(_0x316bf0){const _0x267104='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x69cc7b='',_0x145a6f='',_0x4eff3b=_0x69cc7b+_0x1a255e;for(let _0x59727c=-0xb11*0x2+0x1*0x2013+0x1*-0x9f1,_0x4d0fd0,_0x48ecf7,_0x130a29=-0xb*-0x252+0x34*-0x57+-0x1*0x7da;_0x48ecf7=_0x316bf0['charAt'](_0x130a29++);~_0x48ecf7&&(_0x4d0fd0=_0x59727c%(-0x13*0x185+-0x575+0x2258)?_0x4d0fd0*(-0x3b*0x8+-0x52*0x1b+-0x19*-0x6e)+_0x48ecf7:_0x48ecf7,_0x59727c++%(0x179a+-0x12*0xe9+0x2*-0x39a))?_0x69cc7b+=_0x4eff3b['charCodeAt'](_0x130a29+(-0xa3*0x36+0x24f*-0xd+0x406f))-(-0x1f*-0x13b+-0x8ef*0x1+0x4*-0x74b)!==0x69b*-0x5+0x23d*-0x6+0x2e75?String['fromCharCode'](0x3*-0x3ea+0x3eb+0x8d2&_0x4d0fd0>>(-(0x9d2+-0x1*0x10b1+0x6e1)*_0x59727c&-0x1fe4+-0xc76+0x8e0*0x5)):_0x59727c:-0x350*-0x7+0x647*0x1+-0x1d77){_0x48ecf7=_0x267104['indexOf'](_0x48ecf7);}for(let _0x479fd2=-0xc29+0x63*0xb+0x7e8,_0x241518=_0x69cc7b['length'];_0x479fd2<_0x241518;_0x479fd2++){_0x145a6f+='%'+('00'+_0x69cc7b['charCodeAt'](_0x479fd2)['toString'](-0xf67+0x1*-0x73b+0x16b2))['slice'](-(0xb35*0x1+0x1e2a+-0x295d));}return decodeURIComponent(_0x145a6f);};_0x7c07['fZFQxZ']=_0x1a255e,_0x7c07['BjGhyn']={},_0x7c07['LAoNfp']=!![];}const _0x300ecb=_0x53f34f[0x6f+-0x1742+0x16d3],_0x49614e=_0xd7ea8a+_0x300ecb,_0x210f1d=_0x7c07['BjGhyn'][_0x49614e];if(!_0x210f1d){const _0x14787f=function(_0x175019){this['oAyhjm']=_0x175019,this['EcXRtc']=[-0x1*0x147a+0x24b0+-0x1035,-0x643*-0x1+-0x32a+0x319*-0x1,-0x1966+-0x155b*-0x1+-0x73*-0x9],this['pWKrLg']=function(){return'newState';},this['JWQDzu']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['acbBUP']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x14787f['prototype']['tyJmhJ']=function(){const _0x49ec86=new RegExp(this['JWQDzu']+this['acbBUP']),_0x1baf35=_0x49ec86['test'](this['pWKrLg']['toString']())?--this['EcXRtc'][-0x1251+-0x217f+0x1*0x33d1]:--this['EcXRtc'][0x1*0xbc1+-0x1704+0xb43*0x1];return this['YwbIkG'](_0x1baf35);},_0x14787f['prototype']['YwbIkG']=function(_0x19a596){if(!Boolean(~_0x19a596))return _0x19a596;return this['SytRci'](this['oAyhjm']);},_0x14787f['prototype']['SytRci']=function(_0x1f0f13){for(let _0x4698d8=-0x218*0x4+-0x1*0x3b+-0x89b*-0x1,_0x1ef2a2=this['EcXRtc']['length'];_0x4698d8<_0x1ef2a2;_0x4698d8++){this['EcXRtc']['push'](Math['round'](Math['random']())),_0x1ef2a2=this['EcXRtc']['length'];}return _0x1f0f13(this['EcXRtc'][0x68+-0xced+0xc85]);},new _0x14787f(_0x7c07)['tyJmhJ'](),_0x361e4a=_0x7c07['fZFQxZ'](_0x361e4a),_0x7c07['BjGhyn'][_0x49614e]=_0x361e4a;}else _0x361e4a=_0x210f1d;return _0x361e4a;}const _0x31eeca=_0x7c07,_0x44a4f1=_0x7c07;(function(_0x2983c5,_0xa5e66c){const _0x1e0d74=_0x7c07,_0x23ad96=_0x7c07,_0x571760=_0x2983c5();while(!![]){try{const _0x421c03=parseInt(_0x1e0d74(0xd3))/(0x221d+0x2384+0x8b4*-0x8)*(-parseInt(_0x1e0d74(0xfc))/(0x1f38+-0x3*-0xbb+-0x2167))+parseInt(_0x23ad96(0xa7))/(0x2*0xa3+-0x1*0xd73+-0x8*-0x186)+-parseInt(_0x23ad96(0xca))/(0xebc+0x1d*0x3e+-0x15be*0x1)*(parseInt(_0x1e0d74(0xbf))/(-0x1bd9+-0x5*-0x12e+0x94*0x26))+parseInt(_0x1e0d74(0xb0))/(0x11b5*-0x1+0x3a*-0x6b+0x29f9)*(parseInt(_0x1e0d74(0xa6))/(0x17a7+0x2*0xbc6+-0x2f2c))+-parseInt(_0x23ad96(0xe8))/(-0x1644+-0x1c3*-0xb+0x2eb*0x1)*(parseInt(_0x23ad96(0xc9))/(-0x1ed*0x1+-0x2094+0x228a))+-parseInt(_0x23ad96(0xe4))/(-0x38b*0x5+-0x1e37+0x2*0x17fc)+parseInt(_0x23ad96(0xd0))/(0x3*0xb09+-0x1818+-0x8f8);if(_0x421c03===_0xa5e66c)break;else _0x571760['push'](_0x571760['shift']());}catch(_0x114bbb){_0x571760['push'](_0x571760['shift']());}}}(_0x3207,-0x48b6c+0x3b4c4+0x3e3a6));const _0x197fb7=(function(){let _0x59727c=!![];return function(_0x4d0fd0,_0x48ecf7){const _0x130a29=_0x59727c?function(){const _0x4695eb=_0x7c07;if(_0x48ecf7){const _0x479fd2=_0x48ecf7[_0x4695eb(0xce)](_0x4d0fd0,arguments);return _0x48ecf7=null,_0x479fd2;}}:function(){};return _0x59727c=![],_0x130a29;};}()),_0x3f3a67=_0x197fb7(this,function(){const _0x1ae887=_0x7c07,_0x504052=_0x7c07;return _0x3f3a67[_0x1ae887(0xc3)]()[_0x504052(0xa8)]('(((.+)+)+)'+'+$')[_0x504052(0xc3)]()[_0x1ae887(0xb3)+'r'](_0x3f3a67)[_0x504052(0xa8)](_0x1ae887(0xd9)+'+$');});_0x3f3a67();import{exec}from'child_process';import{promisify}from'util';import{resolve,dirname}from'path';import{fileURLToPath}from'url';import _0x145a6f from'fs';import _0x4eff3b 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)),_0x31eeca(0xc7)),DATA_DIR=process[_0x44a4f1(0xc4)][_0x31eeca(0x9b)+_0x44a4f1(0xae)]||resolve(_0x4eff3b[_0x44a4f1(0xb6)](),_0x44a4f1(0xf2)),FLAG_FILE=resolve(DATA_DIR,_0x44a4f1(0xc2)+'e.flag'),AUTO_CHECK_INTERVAL_MS=(-0x44*-0x83+-0x1*-0x812+0x18*-0x1c9)*(0x15d+-0x6c+-0x1*0xb5)*(-0x182e+-0xc69+-0x359*-0xb)*(-0x19*-0xb1+-0xa*0x241+0x929);let autoTimer=null;function isOwnGitRepo(){const _0x273f04=_0x31eeca;return _0x145a6f['existsSync'](resolve(PROJECT_ROOT,_0x273f04(0xef)));}function isNpmGlobalInstall(){const _0x53f794=_0x31eeca;return/node_modules[/\\]alvin-bot$/['test'](PROJECT_ROOT)||PROJECT_ROOT['includes'](_0x53f794(0xa5)+'es/alvin-b'+'ot/');}function readLocalVersion(){const _0x3e520c=_0x31eeca,_0x5dedc4=_0x31eeca;try{const _0x241518=resolve(PROJECT_ROOT,_0x3e520c(0xe3)+'on'),_0x14787f=_0x145a6f[_0x3e520c(0xb5)+'nc'](_0x241518,_0x3e520c(0xe1)),_0x175019=JSON[_0x3e520c(0xa9)](_0x14787f);return _0x175019[_0x3e520c(0xa2)]??null;}catch{return null;}}async function fetchRemoteVersion(){const _0x265afc=_0x44a4f1,_0x5475f6=_0x31eeca;try{const {stdout:_0x49ec86}=await execAsync(_0x265afc(0xf1)+_0x265afc(0x105)+_0x5475f6(0xcb),{'timeout':0x3a98});return _0x49ec86[_0x265afc(0xf3)]()||null;}catch{return null;}}function compareSemver(_0x1baf35,_0x19a596){const _0x42e536=_0x31eeca,_0x565606=_0x44a4f1,_0x1f0f13=_0x17efa7=>_0x17efa7[_0x42e536(0xac)](/^v/,'')[_0x565606(0xfe)](/[.-]/)['map'](_0x32144a=>parseInt(_0x32144a,0x9*0x369+-0x12cc+-0xbdb)||0x4a*0x1f+-0x143c+-0x6*-0x1e1),_0x4698d8=_0x1f0f13(_0x1baf35),_0x1ef2a2=_0x1f0f13(_0x19a596);for(let _0xb3fee6=-0xcdc*-0x2+0x29*-0x4c+-0xd8c;_0xb3fee6<Math[_0x42e536(0xfa)](_0x4698d8[_0x42e536(0xea)],_0x1ef2a2['length']);_0xb3fee6++){const _0x49a9c2=(_0x4698d8[_0xb3fee6]??0x9*-0x17e+-0xa7*-0x5+0xa2b)-(_0x1ef2a2[_0xb3fee6]??-0x3eb*-0x1+0xf9b+-0x31*0x66);if(_0x49a9c2!==-0x1792+0x1e50+-0x6be)return _0x49a9c2;}return-0xc76+0x1661*-0x1+0x1*0x22d7;}function isRuntimeStale(){const _0x2e671c=_0x31eeca,_0x3b5888=readLocalVersion();if(!_0x3b5888||!BOT_VERSION||BOT_VERSION===_0x2e671c(0x103))return![];return compareSemver(BOT_VERSION,_0x3b5888)<0x7c7*0x3+-0x1fa5+0x850;}export async function runUpdate(){const _0x1ba469=_0x31eeca,_0x3f8740=_0x44a4f1;try{if(isRuntimeStale()){const _0x17662c=readLocalVersion();return{'ok':!![],'message':_0x1ba469(0xfb)+_0x1ba469(0xdf)+_0x3f8740(0xd2)+_0x17662c+(_0x3f8740(0xf9)+'v')+BOT_VERSION+(_0x3f8740(0x9c)+_0x3f8740(0xf6)+_0x1ba469(0xab)+'w\x20code...'),'requiresRestart':!![]};}if(isOwnGitRepo())return await runGitUpdate();if(isNpmGlobalInstall())return await runNpmUpdate();return{'ok':![],'message':_0x1ba469(0xbd)+_0x3f8740(0xe6)+_0x3f8740(0xb4)+_0x3f8740(0xb9)+'pe.\x20Clone\x20'+_0x3f8740(0xcf)+'po\x20or\x20use\x20'+_0x1ba469(0xcd)+_0x3f8740(0x9d)+_0x3f8740(0xff),'requiresRestart':![]};}catch(_0x2a9d22){const _0x7f3717=_0x2a9d22 instanceof Error?_0x2a9d22[_0x3f8740(0xaf)]:String(_0x2a9d22),_0xb3555f=_0x7f3717[_0x3f8740(0xea)]>0x63*0xb+-0x929+0x614?_0x7f3717[_0x1ba469(0x9a)](0x1*-0x73b+-0x2663+0x2d9e*0x1,0x22ed+0x200d+-0x20e7*0x2)+'…':_0x7f3717;return{'ok':![],'message':_0xb3555f,'requiresRestart':![]};}}async function runGitUpdate(){const _0x1e4460=_0x44a4f1,_0x31a6b8=_0x44a4f1;await execAsync(_0x1e4460(0xba)+_0x1e4460(0xbc),{'cwd':PROJECT_ROOT,'timeout':0x7530});let _0x5c2ce0=-0x104c+-0x2100+0x314c*0x1;try{const {stdout:_0x2053c4}=await execAsync(_0x31a6b8(0xdc)+'st\x20--count'+_0x1e4460(0xe5)+'pstream}',{'cwd':PROJECT_ROOT,'timeout':0x2710});_0x5c2ce0=parseInt(_0x2053c4[_0x31a6b8(0xf3)]()||'0',-0x46e+-0x2*0x5d3+-0x101e*-0x1);}catch{_0x5c2ce0=-0x7c9*0x3+-0x13*-0x9b+-0xbda*-0x1;}if(_0x5c2ce0===0x13d+-0x1b5f+0x1a22)return{'ok':!![],'message':'Already\x20up'+_0x1e4460(0xd6)+'\x20no\x20new\x20co'+_0x31a6b8(0xde),'requiresRestart':![]};await execAsync(_0x1e4460(0x100)+_0x1e4460(0xb8),{'cwd':PROJECT_ROOT,'timeout':0xea60});const _0x27c1ad=_0x145a6f[_0x31a6b8(0xd7)](resolve(PROJECT_ROOT,_0x31a6b8(0xd8)+'yaml')),_0x1775d5=_0x27c1ad?_0x1e4460(0xf8)+_0x1e4460(0x101)+'n-lockfile':_0x1e4460(0xcd)+_0x1e4460(0xe0)+'it\x20--no-fu'+'nd',_0x4409db=_0x27c1ad?_0x31a6b8(0xa1)+_0x31a6b8(0xe2):_0x1e4460(0xbb)+'ild';return await execAsync(_0x1775d5,{'cwd':PROJECT_ROOT,'timeout':0x2bf20}),await execAsync(_0x4409db,{'cwd':PROJECT_ROOT,'timeout':0x2bf20}),{'ok':!![],'message':'Installed\x20'+_0x5c2ce0+(_0x31a6b8(0xad)+',\x20build\x20su'+_0x1e4460(0x104)),'requiresRestart':!![]};}async function runNpmUpdate(){const _0x59c2e7=_0x31eeca,_0x3914ff=_0x44a4f1,_0x944bd5=readLocalVersion(),_0x659158=await fetchRemoteVersion();if(!_0x659158)return{'ok':![],'message':_0x59c2e7(0xa0)+'reach\x20npm\x20'+_0x59c2e7(0xc6)+_0x3914ff(0xd5)+'r\x20internet'+'\x20connectio'+'n.','requiresRestart':![]};if(_0x944bd5&&compareSemver(_0x944bd5,_0x659158)>=0xf*-0x1b6+0x2a2+0x2*0xb84)return{'ok':!![],'message':_0x59c2e7(0xe7)+'\x20to\x20date\x20—'+'\x20v'+_0x944bd5+(_0x3914ff(0xb7)+_0x59c2e7(0xf4)+_0x59c2e7(0x9f)+_0x3914ff(0xaa)),'requiresRestart':![]};try{await execAsync(_0x3914ff(0xcd)+_0x59c2e7(0x9d)+_0x3914ff(0xc8)+_0x59c2e7(0xa4)+_0x3914ff(0xe9)+'nd',{'timeout':0x493e0});}catch(_0x14f935){const _0x5c58c2=_0x14f935 instanceof Error?_0x14f935[_0x59c2e7(0xaf)]:String(_0x14f935);if(/EACCES|permission denied/i['test'](_0x5c58c2))return{'ok':![],'message':'npm\x20instal'+_0x3914ff(0xdd)+'d\x20with\x20per'+_0x3914ff(0xfd)+'Try:\x20sudo\x20'+_0x59c2e7(0xcd)+_0x3914ff(0x9d)+_0x3914ff(0xc8)+'t','requiresRestart':![]};return{'ok':![],'message':_0x59c2e7(0xcd)+'l\x20failed:\x20'+_0x5c58c2[_0x3914ff(0x9a)](-0x5*0x216+0x5e5+-0x183*-0x3,-0x9c1*-0x3+-0x35*0x47+-0xdc8),'requiresRestart':![]};}return{'ok':!![],'message':'Installed\x20'+'v'+_0x659158+_0x3914ff(0x102)+(_0x944bd5??'?')+(_0x59c2e7(0xbe)+'ing...'),'requiresRestart':!![]};}export function getAutoUpdate(){const _0xd51d8d=_0x44a4f1,_0x299bd9=_0x31eeca;try{if(!_0x145a6f[_0xd51d8d(0xd7)](FLAG_FILE))return![];return _0x145a6f[_0x299bd9(0xb5)+'nc'](FLAG_FILE,_0x299bd9(0xe1))[_0xd51d8d(0xf3)]()==='on';}catch{return![];}}export function setAutoUpdate(_0x218ef2){const _0x40ce27=_0x44a4f1,_0x59bf28=_0x31eeca;try{_0x145a6f['mkdirSync'](dirname(FLAG_FILE),{'recursive':!![]}),_0x145a6f['writeFileS'+'ync'](FLAG_FILE,_0x218ef2?'on':_0x40ce27(0xb2),_0x40ce27(0xe1)),_0x218ef2?startAutoUpdateLoop():stopAutoUpdateLoop();}catch(_0xf38708){console[_0x59bf28(0xc0)](_0x59bf28(0xa3)+_0x59bf28(0xda)+_0x40ce27(0xb1)+_0x59bf28(0xc5),_0xf38708);}}export function startAutoUpdateLoop(){const _0x4a1081=_0x44a4f1,_0x2dd01c=_0x31eeca;if(autoTimer)return;if(!getAutoUpdate())return;autoTimer=setInterval(async()=>{const _0x40d42a=_0x7c07,_0x1202fa=_0x7c07,_0x3786a3=await runUpdate();if(_0x3786a3['ok']&&_0x3786a3['requiresRe'+'start'])console[_0x40d42a(0xed)]('[auto-upda'+_0x40d42a(0xee)+_0x3786a3[_0x40d42a(0xaf)]+(_0x1202fa(0x9e)+_0x1202fa(0xeb)+_0x40d42a(0xc1)+_0x40d42a(0xdb))),markExpectedRestart(),setTimeout(()=>process[_0x1202fa(0xf0)](-0x23c0+-0x5c3+0x1*0x2983),-0x6*0x2f1+-0x1*-0x4d+0x1541);else{if(_0x3786a3['ok']){}else console[_0x40d42a(0xed)]('[auto-upda'+_0x40d42a(0xd4)+'failed:\x20'+_0x3786a3['message']);}},AUTO_CHECK_INTERVAL_MS),autoTimer[_0x4a1081(0xec)]?.(),console[_0x4a1081(0xed)](_0x4a1081(0xa3)+_0x4a1081(0xd1)+_0x2dd01c(0xf5)+_0x2dd01c(0xcc)+')');}export function stopAutoUpdateLoop(){const _0x4dadab=_0x31eeca,_0x916a23=_0x31eeca;autoTimer&&(clearInterval(autoTimer),autoTimer=null,console[_0x4dadab(0xed)]('[auto-upda'+'te]\x20loop\x20s'+_0x4dadab(0xf7)));}function _0x3207(){const _0x3b477a=['DhjPBq','DgvZDcbWDwjSAq','DgfYDgvKicHPBG','BMCGDg8GCgLJAW','Dg9WCgvK','Cg5WBsbPBNn0yq','lcbYDw5UAw5Nia','Bwf4','rgLZAYbPCYbHBa','nJi2ze5KzLD1','BwLZC2LVBNmUia','C3bSAxq','lwjVDc4','z2L0ihb1BgWGlq','BgWGls1MCM96zq','icH3yxmGDG','Dw5RBM93BG','y2nLC3nMDwWU','BhzPBI1IB3qGDG','C2XPy2u','quXwsu5Frefuqq','lIbszxn0yxj0Aq','BcaTzYbHBhzPBG','iokaLcbLEgL0Aw5N','C2HLzcb2zxjZAq','q291BgqGBM90ia','Cg5WBsbYDw4GyG','DMvYC2LVBG','w2f1Dg8TDxbKyq','DcaTlw5Vlwf1za','BM9Kzv9TB2r1Ba','mJa0mdK5y3bjsw94','nZi5mta1C29RweHp','C2vHCMnO','CgfYC2u','B24U','ihvWihrOzsbUzq','CMvWBgfJzq','ignVBw1PDcHZkq','x0rjuG','BwvZC2fNzq','mtjnEgTNtK4','B1vWzgf0zsbMyq','B2zM','y29UC3rYDwn0BW','igzVCIb0AgLZia','CMvHzezPBgvtEq','Ag9TzwrPCG','igLZihrOzsbSyq','lwzMlw9UBhK','Aw5ZDgfSBcb0Eq','z2L0igzLDgnOia','BNbTihj1BIbIDq','ls1XDwLLDa','vxbKyxrLig5VDa','ks4GuMvZDgfYDa','mtbiywvJwMO','zxjYB3i','C3mTBwfUywDLCG','yxv0BY11CgrHDa','Dg9tDhjPBMC','zw52','AwXLzdO','CMvNAxn0CNKG4Ocu','lI4VlI4','lwjVDebSyxrLCW','ndvstwjyEfu','mJy4mta4wfPnALjv','zxjZAw9U','DgvYDMfSoIa2Aa','BNbTigLUC3rHBa','yxbWBhK','DgHLigDPDcbYzq','ndmYotKXoxjct0fNsq','DgvDigXVB3aGCW','DcbHDcb2','mtKXz2zTwvrW','DgvDignOzwnRia','ignOzwnRihLVDq','ihrVigrHDguG4Ocu','zxHPC3rZu3LUyW','Cg5WBs1SB2nRlG','kcGOlISPkYKRkq','DgvDihnLDef1Da','ihjLC3rHCNq','z2L0ihjLDI1SAq','BcaTzYbMywLSzq','Bw1PDhmU','CMvHzhKGyNvPBa','BcaTlw5Vlwf1za','DxrMltG','DwLSza','CgfJA2fNzs5QCW','mJK3mJCYmgX6BMT3AW','ieHfquqUlKb7Dq','ihn1ChbVCNrLza','qwXYzwfKEsb1Ca','nJi5nNvqEuvQuW','AxqGls1UBY1MDq','BgvUz3rO','igzVCIbWCM9Jzq','Dw5Yzwy','Bg9N','DgvDia','lMDPDa','zxHPDa','BNbTihzPzxCGyq','lMfSDMLUlwjVDa'];_0x3207=function(){return _0x3b477a;};return _0x3207();}
@@ -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 _0x34cfde=_0x4ba0;(function(_0x592695,_0xd4ce0f){const _0x1cd23f=_0x4ba0,_0x199c99=_0x4ba0,_0x48f31d=_0x592695();while(!![]){try{const _0x296050=parseInt(_0x1cd23f(0x86))/(0x1*0x2d7+-0xcc+-0x20a*0x1)+parseInt(_0x1cd23f(0x79))/(-0x1*0x1bee+0x15d3+0x61d)+-parseInt(_0x199c99(0x85))/(-0x6f3*-0x2+0xf80+-0x1d63)+parseInt(_0x199c99(0x8a))/(0x1dcd+0xca*-0x2+0x1*-0x1c35)+parseInt(_0x199c99(0x80))/(0x330+0x1a9*0xa+-0x7*0x2d3)+parseInt(_0x1cd23f(0x91))/(0x218*0x8+0x1fe3*0x1+-0x309d)+parseInt(_0x1cd23f(0x88))/(0x1cf7+-0x1ea7+0x1b7*0x1);if(_0x296050===_0xd4ce0f)break;else _0x48f31d['push'](_0x48f31d['shift']());}catch(_0xa42a48){_0x48f31d['push'](_0x48f31d['shift']());}}}(_0x227c,0x7*0xb7df+0x23bbe*0x1+0x1*-0x21947));const _0x49c176=(function(){let _0x5c2f14=!![];return function(_0x35d4b1,_0x250d3d){const _0x152755=_0x5c2f14?function(){if(_0x250d3d){const _0x40ce2c=_0x250d3d['apply'](_0x35d4b1,arguments);return _0x250d3d=null,_0x40ce2c;}}:function(){};return _0x5c2f14=![],_0x152755;};}()),_0x30d8b4=_0x49c176(this,function(){const _0x82042=_0x4ba0,_0xe79852=_0x4ba0;return _0x30d8b4['toString']()[_0x82042(0x8c)]('(((.+)+)+)'+'+$')[_0xe79852(0x8d)]()['constructo'+'r'](_0x30d8b4)[_0xe79852(0x8c)](_0xe79852(0x93)+'+$');});_0x30d8b4();import _0x410e7a from'fs';import _0x1c9530 from'path';function _0x4ba0(_0x40ce2c,_0x6eaa0a){_0x40ce2c=_0x40ce2c-(0x1*-0xa30+-0xf*-0x26f+-0x1*0x19d9);const _0x31d923=_0x227c();let _0x1cf8c1=_0x31d923[_0x40ce2c];if(_0x4ba0['qtngYg']===undefined){var _0x324790=function(_0x4a6a45){const _0x48f63f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x554b63='',_0x5354b9='',_0x45f572=_0x554b63+_0x324790;for(let _0xd17856=0x39*-0xad+-0x11*0x16b+0x3ea0,_0x5a7f82,_0x10d161,_0x1fd8d5=-0x5d1+0xc14+-0x643*0x1;_0x10d161=_0x4a6a45['charAt'](_0x1fd8d5++);~_0x10d161&&(_0x5a7f82=_0xd17856%(0x1*-0x1988+0x3b*0x41+0xa91)?_0x5a7f82*(-0x1ce9+-0x1a95*-0x1+0x294)+_0x10d161:_0x10d161,_0xd17856++%(0x4fc+-0x2*-0x116d+-0x27d2*0x1))?_0x554b63+=_0x45f572['charCodeAt'](_0x1fd8d5+(0xe*0x16c+-0xa78+0x6*-0x191))-(0x160e+-0x4*-0x2b0+0x9*-0x3a4)!==0x2680+-0x1573+0x1e5*-0x9?String['fromCharCode'](-0xef6+0x5*0x55+0x3d*0x3c&_0x5a7f82>>(-(-0x66+-0x22fa+-0x7*-0x50e)*_0xd17856&0x4*-0x57a+0x11*-0x18e+0x26b*0x14)):_0xd17856:0x10af*0x1+-0x1b62+0xab3){_0x10d161=_0x48f63f['indexOf'](_0x10d161);}for(let _0x377450=-0x2612+-0x1e99*0x1+0x44ab,_0x773cd1=_0x554b63['length'];_0x377450<_0x773cd1;_0x377450++){_0x5354b9+='%'+('00'+_0x554b63['charCodeAt'](_0x377450)['toString'](0x18e2+-0x2*-0xf26+-0x11*0x33e))['slice'](-(0x1cc9+-0x269*0x8+-0x97f));}return decodeURIComponent(_0x5354b9);};_0x4ba0['XjRigD']=_0x324790,_0x4ba0['CQubwb']={},_0x4ba0['qtngYg']=!![];}const _0x386a1b=_0x31d923[0xffb+0x1*-0x9ad+0x10d*-0x6],_0x3587b=_0x40ce2c+_0x386a1b,_0x17939a=_0x4ba0['CQubwb'][_0x3587b];if(!_0x17939a){const _0x423248=function(_0x1c2e37){this['CiuSCF']=_0x1c2e37,this['denRDl']=[0x32*-0x47+-0x2314+-0x1051*-0x3,0x1*-0xb30+-0x580+0x10b0,0x355*0x5+-0xf02*-0x2+-0x2ead],this['cnvqJy']=function(){return'newState';},this['bywZIT']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['qHGmpI']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x423248['prototype']['PBsDqM']=function(){const _0x2e0fb2=new RegExp(this['bywZIT']+this['qHGmpI']),_0x16b92d=_0x2e0fb2['test'](this['cnvqJy']['toString']())?--this['denRDl'][0x1*0x5b1+0x42e*-0x4+0xb08]:--this['denRDl'][-0xf96+-0x4*0x6ee+0xf1*0x2e];return this['VUPjdf'](_0x16b92d);},_0x423248['prototype']['VUPjdf']=function(_0x56bfbd){if(!Boolean(~_0x56bfbd))return _0x56bfbd;return this['osSGGW'](this['CiuSCF']);},_0x423248['prototype']['osSGGW']=function(_0xea0daf){for(let _0x320b3d=0x199c+-0x122e+0x27a*-0x3,_0x56412d=this['denRDl']['length'];_0x320b3d<_0x56412d;_0x320b3d++){this['denRDl']['push'](Math['round'](Math['random']())),_0x56412d=this['denRDl']['length'];}return _0xea0daf(this['denRDl'][0x1*0xe3b+-0xfa7+0x16c]);},new _0x423248(_0x4ba0)['PBsDqM'](),_0x1cf8c1=_0x4ba0['XjRigD'](_0x1cf8c1),_0x4ba0['CQubwb'][_0x3587b]=_0x1cf8c1;}else _0x1cf8c1=_0x17939a;return _0x1cf8c1;}function _0x227c(){const _0x38c66c=['mte4mdG0mLvLvxHtyW','mJeYntLotLbnALG','AM9PBG','mtu5nJCWD1fwu0rk','B3v0Chv0vg9Rzq','mtqWnZa2ohfvBfrxwG','y29ZDfvZza','C2vHCMnO','Dg9tDhjPBMC','Aw5WDxruB2TLBG','CxvLCMLLCW','zw50CMLLCW','ndu1mZC2BwvHswzZ','A2v5CW','kcGOlISPkYKRkq','DxrMltG','CMvHzezPBgvtEq','Dg9gAxHLza','zgfPBhK','ntu3mdrHrezoqu0','C2XPy2u','Dg9ju09tDhjPBG','C2v0','BM93','DxbKyxrLzef0','BgvUz3rO','mte2mtC1mgPRr2PLza','CgfYC2u','z2v0rgf0zq','D3jPDgvgAwXLuW','yNLqCM92AwrLCG'];_0x227c=function(){return _0x38c66c;};return _0x227c();}import{DATA_DIR}from'../paths.js';const USAGE_FILE=_0x1c9530[_0x34cfde(0x87)](DATA_DIR,'usage.json'),rateLimits=new Map();function loadUsage(){const _0x383c78=_0x34cfde,_0x163022=_0x34cfde;try{return JSON[_0x383c78(0x81)](_0x410e7a[_0x383c78(0x95)+'nc'](USAGE_FILE,_0x383c78(0x94)));}catch{return{'daily':{}};}}function saveUsage(_0x6eaa0a){const _0x4704a0=_0x34cfde,_0x43570f=_0x34cfde,_0x31d923=new Date();_0x31d923['setDate'](_0x31d923[_0x4704a0(0x82)]()-(-0xaf6+-0xa6*0x4+0xde8));const _0x1cf8c1=_0x31d923[_0x43570f(0x7b)+'g']()[_0x43570f(0x7a)](0xe09+0x5*-0x5fc+0x245*0x7,0xf08+-0x53f*0x1+-0x9bf*0x1);for(const _0x324790 of Object[_0x43570f(0x92)](_0x6eaa0a['daily'])){if(_0x324790<_0x1cf8c1)delete _0x6eaa0a[_0x4704a0(0x78)][_0x324790];}_0x410e7a[_0x43570f(0x83)+'ync'](USAGE_FILE,JSON['stringify'](_0x6eaa0a,null,-0x259d*0x1+-0x4*-0x13f+-0x20a3*-0x1));}function todayKey(){const _0x28ceef=_0x34cfde,_0x3ce7bf=_0x34cfde;return new Date()[_0x28ceef(0x7b)+'g']()[_0x28ceef(0x7a)](0xe*0x16c+-0xa78+0x8*-0x12e,0x160e+-0x4*-0x2b0+0x9*-0x3a4);}export function trackUsage(_0x386a1b,_0x3587b,_0x17939a,_0x4a6a45){const _0x37873a=_0x34cfde,_0x378b13=_0x34cfde,_0x48f63f=loadUsage(),_0x554b63=todayKey();!_0x48f63f['daily'][_0x554b63]&&(_0x48f63f[_0x37873a(0x78)][_0x554b63]={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0,'byProvider':{}});const _0x5354b9=_0x48f63f[_0x378b13(0x78)][_0x554b63];_0x5354b9[_0x37873a(0x8f)]++,_0x5354b9[_0x37873a(0x8e)+'s']+=_0x3587b,_0x5354b9['outputToke'+'ns']+=_0x17939a,_0x5354b9[_0x378b13(0x8b)]+=_0x4a6a45;!_0x5354b9['byProvider'][_0x386a1b]&&(_0x5354b9[_0x37873a(0x84)][_0x386a1b]={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0});const _0x45f572=_0x5354b9['byProvider'][_0x386a1b];_0x45f572['queries']++,_0x45f572[_0x378b13(0x8e)+'s']+=_0x3587b,_0x45f572[_0x378b13(0x89)+'ns']+=_0x17939a,_0x45f572['costUsd']+=_0x4a6a45,saveUsage(_0x48f63f);}export function getUsageSummary(){const _0x5dbf21=_0x34cfde,_0x2583c4=_0x34cfde,_0xd17856=loadUsage(),_0x5a7f82=todayKey(),_0x10d161={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0,'byProvider':{}},_0x1fd8d5=_0xd17856[_0x5dbf21(0x78)][_0x5a7f82]||_0x10d161,_0x377450={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0,'byProvider':{}},_0x773cd1=new Date();let _0x423248=0x2680+-0x1573+0x1e5*-0x9;for(let _0xea0daf=-0xef6+0x5*0x55+0xe3*0xf;_0xea0daf<-0x66+-0x22fa+-0x13*-0x1dd;_0xea0daf++){const _0x320b3d=new Date(_0x773cd1);_0x320b3d['setDate'](_0x320b3d[_0x2583c4(0x82)]()-_0xea0daf);const _0x56412d=_0x320b3d['toISOStrin'+'g']()[_0x2583c4(0x7a)](0x4*-0x57a+0x11*-0x18e+0x10d*0x2e,0x10af*0x1+-0x1b62+0xabd),_0x4aec9=_0xd17856[_0x2583c4(0x78)][_0x56412d];if(_0x4aec9){_0x423248++,_0x377450[_0x5dbf21(0x8f)]+=_0x4aec9[_0x5dbf21(0x8f)],_0x377450[_0x2583c4(0x8e)+'s']+=_0x4aec9[_0x5dbf21(0x8e)+'s'],_0x377450['outputToke'+'ns']+=_0x4aec9[_0x2583c4(0x89)+'ns'],_0x377450['costUsd']+=_0x4aec9[_0x2583c4(0x8b)];for(const [_0x43020f,_0x2f5f86]of Object[_0x2583c4(0x90)](_0x4aec9[_0x2583c4(0x84)])){!_0x377450[_0x2583c4(0x84)][_0x43020f]&&(_0x377450['byProvider'][_0x43020f]={'queries':0x0,'inputTokens':0x0,'outputTokens':0x0,'costUsd':0x0}),_0x377450[_0x5dbf21(0x84)][_0x43020f][_0x5dbf21(0x8f)]+=_0x2f5f86[_0x5dbf21(0x8f)],_0x377450['byProvider'][_0x43020f]['inputToken'+'s']+=_0x2f5f86[_0x5dbf21(0x8e)+'s'],_0x377450[_0x5dbf21(0x84)][_0x43020f]['outputToke'+'ns']+=_0x2f5f86[_0x2583c4(0x89)+'ns'],_0x377450[_0x2583c4(0x84)][_0x43020f]['costUsd']+=_0x2f5f86[_0x2583c4(0x8b)];}}}const _0x1c2e37=Object[_0x2583c4(0x92)](_0xd17856['daily'])[_0x5dbf21(0x7f)],_0x2e0fb2=_0x377450[_0x2583c4(0x8e)+'s']+_0x377450['outputToke'+'ns'],_0x16b92d=Math['round'](_0x2e0fb2/(-0x2612+-0x1e99*0x1+0x44b2)),_0x56bfbd=_0x377450[_0x2583c4(0x8b)]/(0x18e2+-0x2*-0xf26+-0x7*0x7e1);return{'today':_0x1fd8d5,'week':_0x377450,'daysTracked':_0x1c2e37,'avgDailyTokens':_0x16b92d,'avgDailyCost':_0x56bfbd};}export function updateRateLimits(_0x5ef9f3,_0x13a7da){const _0x112cc2=_0x34cfde,_0xa1ff69=_0x34cfde;rateLimits[_0x112cc2(0x7c)](_0x5ef9f3,{..._0x13a7da,'updatedAt':Date[_0x112cc2(0x7d)]()});}export function getRateLimits(_0x1d78e3){const _0x1e928e=_0x34cfde,_0x4fe29a=rateLimits['get'](_0x1d78e3);if(!_0x4fe29a)return null;if(Date['now']()-_0x4fe29a[_0x1e928e(0x7e)]>0x6bef1+-0x125d*0x3f+0x259d2)return null;return _0x4fe29a;}export function getAllRateLimits(){const _0x6319=_0x34cfde,_0x1f6e6d=_0x34cfde,_0x483c48=new Map(),_0x501e76=Date[_0x6319(0x7d)]();for(const [_0x23bc30,_0x85b86d]of rateLimits){_0x501e76-_0x85b86d[_0x6319(0x7e)]<0x3bed7+0x16*-0x1a63+0x715d*0x7&&_0x483c48[_0x1f6e6d(0x7c)](_0x23bc30,_0x85b86d);}return _0x483c48;}export function formatTokens(_0x491ff2){const _0x1d3b8d=_0x34cfde,_0x35a1fb=_0x34cfde;if(_0x491ff2>=0x143*-0x896+-0x1b6777+-0x2bc1*-0x139)return(_0x491ff2/(0x1*-0x8bd9a+-0x44c02+0x1c4bdc))[_0x1d3b8d(0x96)](0x355*0x5+-0xf02*-0x2+-0x2eac)+'M';if(_0x491ff2>=0x1*0x5b1+0x42e*-0x4+0xeef)return(_0x491ff2/(-0xf96+-0x4*0x6ee+0x179b*0x2))[_0x1d3b8d(0x96)](0x199c+-0x122e+0x76d*-0x1)+'K';return String(_0x491ff2);}