@aiaiaichain/agent 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
  [![Node](https://img.shields.io/badge/node-%3E%3D20-brightgreen?style=flat-square)](https://nodejs.org)
18
18
  [![License: MIT](https://img.shields.io/badge/license-MIT-yellow?style=flat-square)](LICENSE)
19
19
 
20
- [X / Twitter](https://x.com/aiaiaisol)
20
+ [X / Twitter](https://x.com/aiaiaisol) · [aiaiaichain.xyz](https://aiaiaichain.xyz)
21
21
 
22
22
  </div>
23
23
 
@@ -149,7 +149,7 @@ Get an OpenRouter key at https://openrouter.ai/keys
149
149
 
150
150
  ## Links
151
151
 
152
- - [X / Twitter](https://x.com/aiaiaisol)
152
+ - [X / Twitter](https://x.com/aiaiaisol) · [aiaiaichain.xyz](https://aiaiaichain.xyz)
153
153
  - [npm](https://www.npmjs.com/package/@aiaiaichain/agent)
154
154
 
155
155
  ## License
package/dist/cli.js CHANGED
@@ -6,6 +6,7 @@ import { readFileSync, existsSync } from "node:fs";
6
6
  import { resolve, join, dirname } from "node:path";
7
7
  import { homedir } from "node:os";
8
8
  import { fileURLToPath } from "node:url";
9
+ import { execSync } from "node:child_process";
9
10
  import { render } from "ink";
10
11
  import React from "react";
11
12
  import { config as loadDotenv } from "dotenv";
@@ -22,6 +23,10 @@ import { makeTheme } from "./tui/theme.js";
22
23
  import { AgentDir } from "./core/AgentDir.js";
23
24
  import { priceFeed } from "./tools/PriceFeed.js";
24
25
  import { agentWallet, DEPOSIT_WALLET, ACTION_WALLET, SIGNER } from "./wallet/AgentWallet.js";
26
+ import { PROVIDERS, getConfigured, getUnconfigured } from "./providers/ProviderRegistry.js";
27
+ import { env } from "./core/EnvLoader.js";
28
+ import { gmgnHelp, gmgnStatus, saveGmgnApiKey } from "./tools/GmgnIntegration.js";
29
+ import { sessionStore } from "./session/SessionStore.js";
25
30
  const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), ".aiaiai");
26
31
  const envPath = join(AIAIAI_HOME, ".env");
27
32
  if (existsSync(envPath))
@@ -191,6 +196,260 @@ if (subcmd === "actions" || subcmd === "activity") {
191
196
  })();
192
197
  await new Promise(() => { });
193
198
  }
199
+ if (subcmd === "fees") {
200
+ (async () => {
201
+ const { actionFeed } = await import("./wallet/ActionFeed.js");
202
+ const result = await actionFeed.getFeesTool();
203
+ console.log(result.content[0].text);
204
+ process.exit(0);
205
+ })();
206
+ await new Promise(() => { });
207
+ }
208
+ if (subcmd === "keys" || subcmd === "providers") {
209
+ (async () => {
210
+ const readline = await import("node:readline");
211
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
212
+ const ask = (prompt) => new Promise((res) => rl.question(prompt, res));
213
+ const allEnv = env.getAll();
214
+ const configured = getConfigured(allEnv);
215
+ const unconfigured = getUnconfigured(allEnv);
216
+ console.log(T.accent("\n 🔑 AI Model Providers\n"));
217
+ console.log(T.muted(` Configure AI model providers. Add at least one API key to get started.`));
218
+ console.log(T.muted(` ${configured.length}/${PROVIDERS.length} configured\n`));
219
+ // Show configured
220
+ if (configured.length > 0) {
221
+ console.log(T.success(" Configured (" + configured.length + ")"));
222
+ for (const p of configured) {
223
+ const key = allEnv[p.envVar] || "";
224
+ const masked = key.slice(0, 6) + "••••" + key.slice(-4);
225
+ console.log(T.success(` ✓ ${p.name.padEnd(28)} ${masked}`));
226
+ }
227
+ }
228
+ // Show unconfigured
229
+ console.log("\n" + T.warn(" Unconfigured (" + unconfigured.length + ")"));
230
+ for (let i = 0; i < unconfigured.length; i++) {
231
+ const p = unconfigured[i];
232
+ console.log(T.muted(` ${String(i + 1).padStart(2)}. ${p.name}`));
233
+ }
234
+ // Add key flow
235
+ console.log("\n" + T.muted(" Enter number to add a key, 'r' to refresh models, or 'q' to quit:"));
236
+ const input = (await ask(" > ")).trim();
237
+ if (input === "q") {
238
+ rl.close();
239
+ process.exit(0);
240
+ }
241
+ if (input === "r") {
242
+ console.log(T.muted("\n Refreshing models from configured providers..."));
243
+ await modelRegistry.initialise();
244
+ console.log(T.success(` ✓ ${modelRegistry.modelCount} models available from ${modelRegistry.getProviderCount()} providers`));
245
+ rl.close();
246
+ process.exit(0);
247
+ }
248
+ const idx = parseInt(input) - 1;
249
+ if (isNaN(idx) || idx < 0 || idx >= unconfigured.length) {
250
+ console.log(T.error(" Invalid selection."));
251
+ rl.close();
252
+ process.exit(1);
253
+ }
254
+ const provider = unconfigured[idx];
255
+ console.log(T.accent(`\n ${provider.name}`));
256
+ console.log(T.muted(` ${provider.docsUrl}`));
257
+ console.log(T.muted(` Env var: ${provider.envVar}\n`));
258
+ const key = (await ask(` Enter ${provider.name} API key: `)).trim();
259
+ if (!key) {
260
+ console.log(T.error(" Key is required."));
261
+ rl.close();
262
+ process.exit(1);
263
+ }
264
+ // Save to .env
265
+ env.set(provider.envVar, key);
266
+ console.log(T.success(`\n ✓ ${provider.name} key saved to ~/.aiaiai/.env`));
267
+ // Fetch models from this provider
268
+ console.log(T.muted(" Fetching models from " + provider.name + "..."));
269
+ try {
270
+ await modelRegistry.initialise();
271
+ const providerModels = modelRegistry.getProviderModels(provider.id);
272
+ console.log(T.success(` ✓ ${providerModels.length} models available from ${provider.name}`));
273
+ console.log(T.success(` ✓ ${modelRegistry.modelCount} total models from ${modelRegistry.getProviderCount()} providers`));
274
+ }
275
+ catch (e) {
276
+ console.log(T.warn(` ⚠ Could not fetch models: ${e instanceof Error ? e.message : String(e)}`));
277
+ }
278
+ rl.close();
279
+ process.exit(0);
280
+ })().catch(e => { console.error(T.error(`Error: ${e.message}`)); process.exit(1); });
281
+ await new Promise(() => { });
282
+ }
283
+ if (subcmd === "gmgn" || subcmd === "gmgnhelp") {
284
+ const gmgnArgs = args.slice(1);
285
+ if (gmgnArgs.length === 0 || gmgnArgs[0] === "help" || gmgnArgs[0] === "--help") {
286
+ console.log(gmgnHelp());
287
+ process.exit(0);
288
+ }
289
+ if (gmgnArgs[0] === "setup" || gmgnArgs[0] === "config" || gmgnArgs[0] === "key") {
290
+ (async () => {
291
+ const readline = await import("node:readline");
292
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
293
+ const ask = (prompt) => new Promise((res) => rl.question(prompt, res));
294
+ console.log(T.accent("\n 🔍 GMGN API Key Setup\n"));
295
+ console.log(T.muted(" Get your API key at https://gmgn.ai/ai\n"));
296
+ const key = (await ask(" Enter GMGN_API_KEY: ")).trim();
297
+ if (!key) {
298
+ console.log(T.error(" Key is required."));
299
+ rl.close();
300
+ process.exit(1);
301
+ }
302
+ saveGmgnApiKey(key);
303
+ console.log(T.success("\n ✓ GMGN_API_KEY saved to ~/.config/gmgn/.env"));
304
+ console.log(T.muted(" All GMGN commands are now available.\n"));
305
+ rl.close();
306
+ process.exit(0);
307
+ })().catch(e => { console.error(T.error(`Error: ${e.message}`)); process.exit(1); });
308
+ await new Promise(() => { });
309
+ }
310
+ if (gmgnArgs[0] === "status") {
311
+ console.log(gmgnStatus());
312
+ process.exit(0);
313
+ }
314
+ // Forward to gmgn-cli
315
+ try {
316
+ const fullArgs = ["gmgn-cli", ...gmgnArgs];
317
+ const gmgnEnv = {};
318
+ try {
319
+ const f = readFileSync(join(homedir(), ".config", "gmgn", ".env"), "utf-8");
320
+ for (const l of f.split("\n")) {
321
+ const m = l.trim().match(/^([A-Z_]+)=(.*)$/);
322
+ if (m)
323
+ gmgnEnv[m[1]] = m[2];
324
+ }
325
+ }
326
+ catch { /* no gmgn env */ }
327
+ const output = execSync(fullArgs.join(" "), {
328
+ env: { ...process.env, ...gmgnEnv },
329
+ encoding: "utf-8",
330
+ timeout: 30_000,
331
+ });
332
+ process.stdout.write(output);
333
+ }
334
+ catch (e) {
335
+ const msg = e.stderr?.toString() || e.message || "";
336
+ process.stderr.write(`gmgn-cli: ${msg.slice(0, 500)}\n`);
337
+ process.exit(e.status ?? 1);
338
+ }
339
+ process.exit(0);
340
+ }
341
+ if (subcmd === "update" || subcmd === "upgrade") {
342
+ (async () => {
343
+ const pkgName = "@aiaiaichain/agent";
344
+ console.log(T.accent("\n 🤖 AIAIAI Update Check\n"));
345
+ // Get current version
346
+ const __filename = fileURLToPath(import.meta.url);
347
+ const __dir = dirname(__filename);
348
+ const currentPkg = JSON.parse(readFileSync(resolve(__dir, "..", "package.json"), "utf-8"));
349
+ const current = currentPkg.version;
350
+ console.log(T.muted(` Current version: v${current}`));
351
+ // Check npm for latest
352
+ let latest = null;
353
+ let changelog = "";
354
+ try {
355
+ const viewOutput = execSync(`npm view ${pkgName} version`, {
356
+ encoding: "utf-8",
357
+ timeout: 15_000,
358
+ }).trim();
359
+ latest = viewOutput.split("\n").pop() || null;
360
+ // Try to get changelog from npm
361
+ try {
362
+ const changelogOutput = execSync(`npm view ${pkgName} --json`, {
363
+ encoding: "utf-8",
364
+ timeout: 15_000,
365
+ });
366
+ const pkgData = JSON.parse(changelogOutput);
367
+ if (pkgData.gitHead) {
368
+ changelog = `Git: ${pkgData.gitHead.slice(0, 8)}`;
369
+ }
370
+ }
371
+ catch { /* no changelog available */ }
372
+ }
373
+ catch {
374
+ console.log(T.error(" Could not reach npm registry. Check your connection."));
375
+ process.exit(1);
376
+ }
377
+ if (!latest) {
378
+ console.log(T.error(" Could not determine latest version."));
379
+ process.exit(1);
380
+ }
381
+ console.log(T.muted(` Latest version: v${latest}`));
382
+ if (changelog)
383
+ console.log(T.muted(` ${changelog}`));
384
+ if (latest === current) {
385
+ console.log(T.success("\n ✅ You're on the latest version!\n"));
386
+ process.exit(0);
387
+ }
388
+ console.log(T.accent(`\n ⚡ Update available: v${current} → v${latest}\n`));
389
+ // Ask to update
390
+ const readline = await import("node:readline");
391
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
392
+ const ask = (prompt) => new Promise((res) => rl.question(prompt, res));
393
+ const confirm = (await ask(" Install update now? (y/n): ")).trim().toLowerCase();
394
+ if (confirm !== "y" && confirm !== "yes") {
395
+ console.log(T.muted("\n Skipped. Run `aiaiai update` anytime to update.\n"));
396
+ rl.close();
397
+ process.exit(0);
398
+ }
399
+ console.log(T.muted("\n Installing update..."));
400
+ try {
401
+ execSync(`npm install -g ${pkgName}`, {
402
+ stdio: "inherit",
403
+ timeout: 120_000,
404
+ });
405
+ console.log(T.success(`\n ✅ Updated to v${latest}!`));
406
+ console.log(T.muted(" Run `aiaiai` to restart with new features.\n"));
407
+ }
408
+ catch (e) {
409
+ console.log(T.error(`\n ❌ Update failed: ${e.message}`));
410
+ console.log(T.muted(" Try manually: npm install -g @aiaiaichain/agent\n"));
411
+ }
412
+ rl.close();
413
+ process.exit(0);
414
+ })().catch(e => { console.error(T.error(`Error: ${e.message}`)); process.exit(1); });
415
+ await new Promise(() => { });
416
+ }
417
+ if (subcmd === "sessions") {
418
+ const sessions = sessionStore.list();
419
+ if (sessions.length === 0) {
420
+ console.log(T.muted(" No saved sessions."));
421
+ process.exit(0);
422
+ }
423
+ console.log(T.accent("\n 📂 Saved Sessions\n"));
424
+ sessions.slice(0, 15).forEach((s, i) => {
425
+ const date = new Date(s.updatedAt).toLocaleDateString();
426
+ console.log(T.muted(` ${String(i + 1).padStart(2)}. ${s.title} (${s.messageCount} msgs, ${s.model}, ${date})`));
427
+ });
428
+ console.log("");
429
+ process.exit(0);
430
+ }
431
+ if (subcmd === "resume") {
432
+ const sessions = sessionStore.list();
433
+ if (sessions.length === 0) {
434
+ console.log(T.muted(" No saved sessions."));
435
+ process.exit(0);
436
+ }
437
+ const idx = parseInt(process.argv[3]) - 1;
438
+ if (isNaN(idx) || idx < 0 || idx >= sessions.length) {
439
+ console.log(T.error(" Invalid session number."));
440
+ process.exit(1);
441
+ }
442
+ const session = sessionStore.load(sessions[idx].id);
443
+ if (!session) {
444
+ console.log(T.error(" Session not found."));
445
+ process.exit(1);
446
+ }
447
+ console.log(T.accent(`\n 📂 Resumed: ${session.title}\n`));
448
+ console.log(T.muted(` Messages: ${session.messages.length}`));
449
+ console.log(T.muted(` Model: ${session.model}`));
450
+ console.log("");
451
+ process.exit(0);
452
+ }
194
453
  // ── Resolve extension + prompt ────────────────────────────────────────────────
195
454
  let extensionPath = null;
196
455
  let promptPath = null;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * EnvLoader — loads environment variables from ~/.aiaiai/.env and process.env
2
+ * EnvLoader — loads/writes environment variables from ~/.aiaiai/.env
3
3
  */
4
4
  export declare class EnvLoader {
5
5
  private cache;
@@ -9,6 +9,9 @@ export declare class EnvLoader {
9
9
  get(key: string, defaultValue?: string): string | undefined;
10
10
  getRequired(key: string): string;
11
11
  has(key: string): boolean;
12
+ /** Write a key=value to the .env file and update cache */
13
+ set(key: string, value: string): void;
14
+ getAll(): Record<string, string>;
12
15
  reload(): void;
13
16
  }
14
17
  export declare const env: EnvLoader;
@@ -1,40 +1,37 @@
1
1
  /**
2
- * EnvLoader — loads environment variables from ~/.aiaiai/.env and process.env
2
+ * EnvLoader — loads/writes environment variables from ~/.aiaiai/.env
3
3
  */
4
- import { existsSync, readFileSync } from 'node:fs';
5
- import { resolve } from 'node:path';
6
- import { homedir } from 'node:os';
4
+ import { existsSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
5
+ import { resolve } from "node:path";
6
+ import { homedir } from "node:os";
7
7
  export class EnvLoader {
8
8
  cache = {};
9
9
  envPath;
10
10
  constructor() {
11
11
  const home = process.env.AIAIAI_HOME ?? resolve(homedir(), '.aiaiai');
12
- this.envPath = resolve(home, '.env');
12
+ this.envPath = resolve(home, ".env");
13
13
  this.load();
14
14
  }
15
15
  load() {
16
- // Load from .env file
17
16
  if (existsSync(this.envPath)) {
18
- const content = readFileSync(this.envPath, 'utf-8');
19
- for (const line of content.split('\n')) {
17
+ const content = readFileSync(this.envPath, "utf-8");
18
+ for (const line of content.split("\n")) {
20
19
  const trimmed = line.trim();
21
- if (!trimmed || trimmed.startsWith('#'))
20
+ if (!trimmed || trimmed.startsWith("#"))
22
21
  continue;
23
- const eqIdx = trimmed.indexOf('=');
22
+ const eqIdx = trimmed.indexOf("=");
24
23
  if (eqIdx === -1)
25
24
  continue;
26
25
  const key = trimmed.slice(0, eqIdx).trim();
27
- const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, '');
26
+ const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, "");
28
27
  if (key)
29
28
  this.cache[key] = value;
30
29
  }
31
30
  }
32
- // Process.env overrides file
33
31
  for (const key of Object.keys(process.env)) {
34
32
  const value = process.env[key];
35
- if (value !== undefined) {
33
+ if (value !== undefined)
36
34
  this.cache[key] = value;
37
- }
38
35
  }
39
36
  }
40
37
  get(key, defaultValue) {
@@ -47,7 +44,42 @@ export class EnvLoader {
47
44
  return value;
48
45
  }
49
46
  has(key) {
50
- return this.cache[key] !== undefined;
47
+ return this.cache[key] !== undefined && this.cache[key].trim() !== "";
48
+ }
49
+ /** Write a key=value to the .env file and update cache */
50
+ set(key, value) {
51
+ const content = existsSync(this.envPath) ? readFileSync(this.envPath, "utf-8") : "";
52
+ const lines = content.split("\n");
53
+ let found = false;
54
+ for (let i = 0; i < lines.length; i++) {
55
+ const line = lines[i].trim();
56
+ if (line.startsWith(`${key}=`)) {
57
+ lines[i] = `${key}=${value}`;
58
+ found = true;
59
+ break;
60
+ }
61
+ }
62
+ if (!found) {
63
+ if (content && !content.endsWith("\n"))
64
+ lines.push("");
65
+ lines.push(`${key}=${value}`);
66
+ }
67
+ const newContent = lines.join("\n") + "\n";
68
+ writeFileSync(this.envPath, newContent, "utf-8");
69
+ try {
70
+ chmodSync(this.envPath, 0o600);
71
+ }
72
+ catch { /* non-fatal */ }
73
+ this.cache[key] = value;
74
+ process.env[key] = value;
75
+ }
76
+ getAll() {
77
+ const result = {};
78
+ for (const [key, value] of Object.entries(this.cache)) {
79
+ if (value !== undefined)
80
+ result[key] = value;
81
+ }
82
+ return result;
51
83
  }
52
84
  reload() {
53
85
  this.cache = {};
@@ -0,0 +1,35 @@
1
+ /**
2
+ * SystemMonitor — tracks CPU, RAM, network, and agent stats.
3
+ * Uses Node.js built-in modules only (no external deps).
4
+ */
5
+ export interface SystemStats {
6
+ cpuPercent: number;
7
+ ramPercent: number;
8
+ ramUsed: string;
9
+ ramTotal: string;
10
+ uptime: string;
11
+ netUp: string;
12
+ netDown: string;
13
+ apiCallsPerMin: number;
14
+ tokensUsed: number;
15
+ }
16
+ export declare class SystemMonitor {
17
+ private apiCallCount;
18
+ private lastNetStats;
19
+ constructor();
20
+ private initNetStats;
21
+ /** Track an API call */
22
+ trackApiCall(): void;
23
+ /** Get current system stats */
24
+ getStats(tokenCount?: number): SystemStats;
25
+ private getCpuPercent;
26
+ private getRamPercent;
27
+ private getNetStats;
28
+ private getRawNetStats;
29
+ private formatBytes;
30
+ private formatUptime;
31
+ /** Reset API call counter (call every minute) */
32
+ resetApiCounter(): number;
33
+ }
34
+ export declare const systemMonitor: SystemMonitor;
35
+ //# sourceMappingURL=SystemMonitor.d.ts.map
@@ -0,0 +1,115 @@
1
+ /**
2
+ * SystemMonitor — tracks CPU, RAM, network, and agent stats.
3
+ * Uses Node.js built-in modules only (no external deps).
4
+ */
5
+ import { cpus, totalmem, freemem, uptime, networkInterfaces } from 'node:os';
6
+ export class SystemMonitor {
7
+ apiCallCount = 0;
8
+ lastNetStats = { rx: 0, tx: 0, time: Date.now() };
9
+ constructor() {
10
+ this.initNetStats();
11
+ }
12
+ initNetStats() {
13
+ try {
14
+ const stats = this.getRawNetStats();
15
+ this.lastNetStats = { rx: stats.rx, tx: stats.tx, time: Date.now() };
16
+ }
17
+ catch { /* non-fatal */ }
18
+ }
19
+ /** Track an API call */
20
+ trackApiCall() {
21
+ this.apiCallCount++;
22
+ }
23
+ /** Get current system stats */
24
+ getStats(tokenCount = 0) {
25
+ return {
26
+ cpuPercent: this.getCpuPercent(),
27
+ ramPercent: this.getRamPercent(),
28
+ ramUsed: this.formatBytes(totalmem() - freemem()),
29
+ ramTotal: this.formatBytes(totalmem()),
30
+ uptime: this.formatUptime(uptime()),
31
+ ...this.getNetStats(),
32
+ apiCallsPerMin: this.apiCallCount,
33
+ tokensUsed: tokenCount,
34
+ };
35
+ }
36
+ getCpuPercent() {
37
+ try {
38
+ const cpuInfo = cpus();
39
+ let totalIdle = 0, totalTick = 0;
40
+ for (const cpu of cpuInfo) {
41
+ for (const type in cpu.times) {
42
+ totalTick += cpu.times[type];
43
+ }
44
+ totalIdle += cpu.times.idle;
45
+ }
46
+ const idle = totalIdle / cpuInfo.length;
47
+ const total = totalTick / cpuInfo.length;
48
+ return Math.round((1 - idle / total) * 100);
49
+ }
50
+ catch {
51
+ return 0;
52
+ }
53
+ }
54
+ getRamPercent() {
55
+ const used = totalmem() - freemem();
56
+ return Math.round((used / totalmem()) * 100);
57
+ }
58
+ getNetStats() {
59
+ try {
60
+ const current = this.getRawNetStats();
61
+ const elapsed = (Date.now() - this.lastNetStats.time) / 1000;
62
+ if (elapsed < 1)
63
+ return { netUp: '0 B/s', netDown: '0 B/s' };
64
+ const rxPerSec = Math.max(0, (current.rx - this.lastNetStats.rx) / elapsed);
65
+ const txPerSec = Math.max(0, (current.tx - this.lastNetStats.tx) / elapsed);
66
+ this.lastNetStats = { rx: current.rx, tx: current.tx, time: Date.now() };
67
+ return {
68
+ netUp: this.formatBytes(txPerSec) + '/s',
69
+ netDown: this.formatBytes(rxPerSec) + '/s',
70
+ };
71
+ }
72
+ catch {
73
+ return { netUp: 'N/A', netDown: 'N/A' };
74
+ }
75
+ }
76
+ getRawNetStats() {
77
+ let rx = 0, tx = 0;
78
+ const interfaces = networkInterfaces();
79
+ for (const name of Object.keys(interfaces)) {
80
+ const iface = interfaces[name];
81
+ if (!iface)
82
+ continue;
83
+ for (const info of iface) {
84
+ if (info.internal)
85
+ continue;
86
+ // Node.js doesn't expose per-interface bytes by default
87
+ // This is a best-effort approximation
88
+ }
89
+ }
90
+ return { rx, tx };
91
+ }
92
+ formatBytes(bytes) {
93
+ if (bytes === 0)
94
+ return '0 B';
95
+ const k = 1024;
96
+ const sizes = ['B', 'KB', 'MB', 'GB'];
97
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
98
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
99
+ }
100
+ formatUptime(seconds) {
101
+ const h = Math.floor(seconds / 3600);
102
+ const m = Math.floor((seconds % 3600) / 60);
103
+ if (h > 0)
104
+ return `${h}h ${m}m`;
105
+ return `${m}m`;
106
+ }
107
+ /** Reset API call counter (call every minute) */
108
+ resetApiCounter() {
109
+ const count = this.apiCallCount;
110
+ this.apiCallCount = 0;
111
+ return count;
112
+ }
113
+ }
114
+ export const systemMonitor = new SystemMonitor();
115
+ //# sourceMappingURL=SystemMonitor.js.map
package/dist/index.d.ts CHANGED
@@ -17,13 +17,13 @@ export { loadExtension } from "./loader.js";
17
17
  export { makeTheme, T, AIAIAI_COLORS } from "./tui/theme.js";
18
18
  export { ModelRegistry, modelRegistry, classifyModel } from "./models/ModelRegistry.js";
19
19
  export { CostTracker } from "./models/CostTracker.js";
20
- export type { OpenRouterModel, TieredModel, TieredPool, ModelTier } from "./models/ModelRegistry.js";
20
+ export type { ModelInfo, TieredModel, ModelTier } from "./models/ModelRegistry.js";
21
21
  export { fullAnalysis, rsi, macd, ema, sma, bollingerBands, atr, getCandlesTool, getCandlesParams } from "./tools/TechnicalAnalysis.js";
22
22
  export { PriceFeed, priceFeed } from "./tools/PriceFeed.js";
23
23
  export { NewsFeed, newsFeed, getNewsTool, scoreSentiment } from "./tools/NewsSentiment.js";
24
24
  export { getFearGreedTool, getFundingRatesTool, getBtcMempoolTool, getDefiTvlTool, getSolanaStatsTool, } from "./tools/MarketSentiment.js";
25
25
  export type { OHLCV, AnalysisResult } from "./tools/TechnicalAnalysis.js";
26
- export type { PriceResult, DexScreenerPair } from "./tools/PriceFeed.js";
26
+ export type { PriceResult, DexScreenerPair as DexScreenerData } from "./tools/PriceFeed.js";
27
27
  export type { NewsItem, SentimentReport } from "./tools/NewsSentiment.js";
28
28
  export { SessionManager } from "./session/SessionManager.js";
29
29
  export { MemoryStore, memoryStore } from "./session/MemoryStore.js";
@@ -37,6 +37,12 @@ export { agentWallet, COLD_WALLET, ACTION_WALLET, DEPOSIT_WALLET, SIGNER, AIAIAI
37
37
  export { actionFeed } from "./wallet/ActionFeed.js";
38
38
  export type { WalletBalance, AgentWallets } from "./wallet/AgentWallet.js";
39
39
  export type { AgentAction, ActionType, FeeTracker } from "./wallet/ActionFeed.js";
40
+ export { gmgnTool, gmgnMarketTool, gmgnHelp, gmgnStatus, hasGmgnApiKey, saveGmgnApiKey, GMGN_SUBCOMMANDS } from "./tools/GmgnIntegration.js";
41
+ export { watchTokenTool, removeWatchTool, listWatchTool, addAlertTool, checkAlertsTool, compareTokensTool, portfolioTool, portfolioParams, getWatchList, checkAlerts, addAlert, getActiveAlerts, } from "./tools/CrossTools.js";
42
+ export { sessionStore } from "./session/SessionStore.js";
43
+ export type { Session, SessionMeta } from "./session/SessionStore.js";
44
+ export { systemMonitor } from "./core/SystemMonitor.js";
45
+ export type { SystemStats } from "./core/SystemMonitor.js";
40
46
  export { MCPServer } from "./mcp/server.js";
41
47
  export { AgentDir } from "./core/AgentDir.js";
42
48
  export { EnvLoader, env } from "./core/EnvLoader.js";
package/dist/index.js CHANGED
@@ -36,6 +36,14 @@ export { AgentScheduler, agentScheduler } from "./scheduler/AgentScheduler.js";
36
36
  // Wallet
37
37
  export { agentWallet, COLD_WALLET, ACTION_WALLET, DEPOSIT_WALLET, SIGNER, AIAIAI_MINT } from "./wallet/AgentWallet.js";
38
38
  export { actionFeed } from "./wallet/ActionFeed.js";
39
+ // GMGN
40
+ export { gmgnTool, gmgnMarketTool, gmgnHelp, gmgnStatus, hasGmgnApiKey, saveGmgnApiKey, GMGN_SUBCOMMANDS } from "./tools/GmgnIntegration.js";
41
+ // Cross tools
42
+ export { watchTokenTool, removeWatchTool, listWatchTool, addAlertTool, checkAlertsTool, compareTokensTool, portfolioTool, portfolioParams, getWatchList, checkAlerts, addAlert, getActiveAlerts, } from "./tools/CrossTools.js";
43
+ // Session
44
+ export { sessionStore } from "./session/SessionStore.js";
45
+ // System
46
+ export { systemMonitor } from "./core/SystemMonitor.js";
39
47
  // MCP
40
48
  export { MCPServer } from "./mcp/server.js";
41
49
  // Core
@@ -23,14 +23,8 @@ export class CostTracker {
23
23
  this.sessionEntry.totalCost += cost;
24
24
  this.sessionEntry.totalTokens += promptTokens + completionTokens;
25
25
  }
26
- estimateCost(model, prompt, completion) {
27
- const all = this.registry.getAllModels();
28
- const m = all.find(m => m.id === model);
29
- if (!m)
30
- return (prompt + completion) * 0.000001;
31
- const p = parseFloat(m.pricing.prompt) || DEFAULT_RATES.prompt;
32
- const c = parseFloat(m.pricing.completion) || DEFAULT_RATES.completion;
33
- return (prompt * p) + (completion * c);
26
+ estimateCost(_model, prompt, completion) {
27
+ return (prompt * DEFAULT_RATES.prompt) + (completion * DEFAULT_RATES.completion);
34
28
  }
35
29
  statusLine() {
36
30
  return `$${this.sessionEntry.totalCost.toFixed(4)}`;