@aiaiaichain/agent 0.1.6 → 0.1.7

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 (121) hide show
  1. package/dist/api/ExtensionAPI.d.ts +0 -1
  2. package/dist/api/ExtensionAPI.js +3 -7
  3. package/dist/api/Registry.d.ts +0 -1
  4. package/dist/api/Registry.js +54 -57
  5. package/dist/cli.d.ts +0 -1
  6. package/dist/cli.js +683 -686
  7. package/dist/core/AgentDir.d.ts +1 -1
  8. package/dist/core/AgentDir.js +45 -39
  9. package/dist/core/ChainConfig.d.ts +0 -1
  10. package/dist/core/ChainConfig.js +51 -55
  11. package/dist/core/EnvLoader.d.ts +4 -1
  12. package/dist/core/EnvLoader.js +97 -84
  13. package/dist/core/SystemMonitor.d.ts +0 -1
  14. package/dist/core/SystemMonitor.js +72 -85
  15. package/dist/index.d.ts +0 -1
  16. package/dist/index.js +19 -26
  17. package/dist/loader.d.ts +0 -1
  18. package/dist/loader.js +64 -67
  19. package/dist/mcp/entry.d.ts +0 -1
  20. package/dist/mcp/entry.js +3 -6
  21. package/dist/mcp/server.d.ts +0 -1
  22. package/dist/mcp/server.js +152 -156
  23. package/dist/models/CostTracker.d.ts +0 -1
  24. package/dist/models/CostTracker.js +58 -61
  25. package/dist/models/ModelRegistry.d.ts +0 -1
  26. package/dist/models/ModelRegistry.js +195 -155
  27. package/dist/providers/ProviderRegistry.d.ts +0 -1
  28. package/dist/providers/ProviderRegistry.js +33 -36
  29. package/dist/runner/AgentRunner.d.ts +0 -1
  30. package/dist/runner/AgentRunner.js +180 -184
  31. package/dist/runner/ModelClient.d.ts +0 -1
  32. package/dist/runner/ModelClient.js +133 -134
  33. package/dist/runner/SwarmRouter.d.ts +0 -1
  34. package/dist/runner/SwarmRouter.js +18 -22
  35. package/dist/runner/ToolDispatcher.d.ts +0 -1
  36. package/dist/runner/ToolDispatcher.js +30 -33
  37. package/dist/scheduler/AgentScheduler.d.ts +0 -1
  38. package/dist/scheduler/AgentScheduler.js +99 -103
  39. package/dist/session/ContextStore.d.ts +1 -1
  40. package/dist/session/ContextStore.js +76 -78
  41. package/dist/session/GoalManager.d.ts +0 -1
  42. package/dist/session/GoalManager.js +96 -100
  43. package/dist/session/MemoryStore.d.ts +2 -1
  44. package/dist/session/MemoryStore.js +108 -87
  45. package/dist/session/SessionManager.d.ts +5 -4
  46. package/dist/session/SessionManager.js +83 -62
  47. package/dist/session/SessionStore.d.ts +0 -1
  48. package/dist/session/SessionStore.js +112 -116
  49. package/dist/setup/SetupWizard.d.ts +0 -1
  50. package/dist/setup/SetupWizard.js +61 -64
  51. package/dist/tools/CrossTools.d.ts +0 -1
  52. package/dist/tools/CrossTools.js +140 -144
  53. package/dist/tools/GmgnIntegration.d.ts +0 -1
  54. package/dist/tools/GmgnIntegration.js +220 -230
  55. package/dist/tools/MarketSentiment.d.ts +0 -1
  56. package/dist/tools/MarketSentiment.js +213 -195
  57. package/dist/tools/NewsSentiment.d.ts +0 -1
  58. package/dist/tools/NewsSentiment.js +126 -130
  59. package/dist/tools/PriceFeed.d.ts +6 -1
  60. package/dist/tools/PriceFeed.js +201 -133
  61. package/dist/tools/TechnicalAnalysis.d.ts +1 -2
  62. package/dist/tools/TechnicalAnalysis.js +248 -216
  63. package/dist/tools/TechnicalAnalysis.worker.d.ts +25 -0
  64. package/dist/tools/TechnicalAnalysis.worker.js +92 -0
  65. package/dist/tools/TokenCalendar.d.ts +0 -1
  66. package/dist/tools/TokenCalendar.js +63 -68
  67. package/dist/tools/TokenSecurityScanner.d.ts +0 -1
  68. package/dist/tools/TokenSecurityScanner.js +93 -96
  69. package/dist/tools/TransactionSim.d.ts +0 -1
  70. package/dist/tools/TransactionSim.js +65 -71
  71. package/dist/tui/App.d.ts +0 -1
  72. package/dist/tui/App.js +895 -824
  73. package/dist/tui/ModelSelector.d.ts +0 -1
  74. package/dist/tui/ModelSelector.js +46 -49
  75. package/dist/tui/REPL.d.ts +0 -1
  76. package/dist/tui/REPL.js +222 -210
  77. package/dist/tui/Sparkline.d.ts +0 -1
  78. package/dist/tui/Sparkline.js +36 -37
  79. package/dist/tui/StatusBar.d.ts +0 -1
  80. package/dist/tui/StatusBar.js +9 -10
  81. package/dist/tui/ThemePresets.d.ts +0 -1
  82. package/dist/tui/ThemePresets.js +99 -103
  83. package/dist/tui/theme.d.ts +0 -1
  84. package/dist/tui/theme.js +50 -31
  85. package/dist/util/clipboard.d.ts +0 -1
  86. package/dist/util/clipboard.js +16 -20
  87. package/dist/util/commandSuggest.d.ts +0 -1
  88. package/dist/util/commandSuggest.js +34 -38
  89. package/dist/util/confirmation.d.ts +0 -1
  90. package/dist/util/confirmation.js +8 -11
  91. package/dist/util/errorHandler.d.ts +0 -1
  92. package/dist/util/errorHandler.js +20 -23
  93. package/dist/util/errors.d.ts +59 -0
  94. package/dist/util/errors.js +93 -0
  95. package/dist/util/logger.d.ts +0 -1
  96. package/dist/util/logger.js +30 -33
  97. package/dist/util/processManager.d.ts +0 -1
  98. package/dist/util/processManager.js +33 -36
  99. package/dist/util/resilientFetch.d.ts +6 -1
  100. package/dist/util/resilientFetch.js +134 -80
  101. package/dist/util/responseCache.d.ts +0 -1
  102. package/dist/util/responseCache.js +36 -45
  103. package/dist/util/rpc.d.ts +16 -0
  104. package/dist/util/rpc.js +69 -0
  105. package/dist/util/safeLog.d.ts +0 -1
  106. package/dist/util/safeLog.js +52 -53
  107. package/dist/util/scheduler.d.ts +0 -1
  108. package/dist/util/scheduler.js +53 -58
  109. package/dist/util/webhooks.d.ts +0 -1
  110. package/dist/util/webhooks.js +54 -58
  111. package/dist/wallet/ActionFeed.d.ts +0 -1
  112. package/dist/wallet/ActionFeed.js +189 -200
  113. package/dist/wallet/AgentWallet.d.ts +7 -8
  114. package/dist/wallet/AgentWallet.js +117 -144
  115. package/dist/wallet/ProfitTracker.d.ts +0 -1
  116. package/dist/wallet/ProfitTracker.js +71 -74
  117. package/package.json +11 -6
  118. package/scripts/build-esbuild.mjs +40 -0
  119. package/scripts/bundle-dts.mjs +58 -0
  120. package/scripts/minify.mjs +44 -0
  121. package/scripts/postinstall.js +27 -0
@@ -1,54 +1,45 @@
1
- /**
2
- * src/util/responseCache.ts — TTL-based response cache for external APIs
3
- */
1
+
4
2
  const cache = new Map();
5
3
  const DEFAULT_TTL_MS = 60_000;
6
- /**
7
- * Get cached value or undefined if expired/missing.
8
- */
4
+
9
5
  export function getCached(key) {
10
- const entry = cache.get(key);
11
- if (!entry)
12
- return undefined;
13
- if (Date.now() > entry.expiresAt) {
14
- cache.delete(key);
15
- return undefined;
16
- }
17
- return entry.data;
18
- }
19
- /**
20
- * Set value in cache with TTL (default 60s).
21
- */
6
+ const entry = cache.get(key);
7
+ if (!entry)
8
+ return undefined;
9
+ if (Date.now() > entry.expiresAt) {
10
+ cache.delete(key);
11
+ return undefined;
12
+ }
13
+ return entry.data;
14
+ }
15
+
22
16
  export function setCache(key, data, ttlMs = DEFAULT_TTL_MS) {
23
- cache.set(key, { data, expiresAt: Date.now() + ttlMs });
24
- // Evict oldest if cache grows too large
25
- if (cache.size > 200) {
26
- const firstKey = cache.keys().next().value;
27
- if (firstKey)
28
- cache.delete(firstKey);
29
- }
30
- }
31
- /**
32
- * Get or compute: return cached value, or compute, cache, and return.
33
- */
17
+ cache.set(key, { data, expiresAt: Date.now() + ttlMs });
18
+
19
+ if (cache.size > 200) {
20
+ const keys = [...cache.keys()];
21
+ const toEvict = Math.ceil(keys.length * 0.2);
22
+ for (let i = 0; i < toEvict; i++) {
23
+ const idx = Math.floor(Math.random() * keys.length);
24
+ cache.delete(keys[idx]);
25
+ keys.splice(idx, 1);
26
+ }
27
+ }
28
+ }
29
+
34
30
  export async function getOrCompute(key, compute, ttlMs = DEFAULT_TTL_MS) {
35
- const cached = getCached(key);
36
- if (cached !== undefined)
37
- return cached;
38
- const result = await compute();
39
- setCache(key, result, ttlMs);
40
- return result;
41
- }
42
- /**
43
- * Clear all cached values.
44
- */
31
+ const cached = getCached(key);
32
+ if (cached !== undefined)
33
+ return cached;
34
+ const result = await compute();
35
+ setCache(key, result, ttlMs);
36
+ return result;
37
+ }
38
+
45
39
  export function clearCache() {
46
- cache.clear();
40
+ cache.clear();
47
41
  }
48
- /**
49
- * Get cache stats for diagnostics.
50
- */
42
+
51
43
  export function cacheStats() {
52
- return { size: cache.size, entries: [...cache.keys()] };
44
+ return { size: cache.size, entries: [...cache.keys()] };
53
45
  }
54
- //# sourceMappingURL=responseCache.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * #55: Fallback RPC endpoints
3
+ * #177: Multiple RPC endpoint support
4
+ * #184: RPC benchmark on startup
5
+ */
6
+ export interface RpcEndpoint {
7
+ url: string;
8
+ name: string;
9
+ priority: number;
10
+ }
11
+ export declare function getEndpoints(): RpcEndpoint[];
12
+ export declare function getCurrentEndpoint(): RpcEndpoint;
13
+ export declare function getRpcUrl(): string;
14
+ export declare function setEndpoints(endpoints: RpcEndpoint[]): void;
15
+ export declare function benchmarkEndpoints(): Promise<void>;
16
+ export declare function rpcCall(method: string, params?: unknown[]): Promise<any>;
@@ -0,0 +1,69 @@
1
+
2
+ import { resilientFetch } from './resilientFetch.js';
3
+ import { errorAggregator } from './errors.js';
4
+ const DEFAULT_ENDPOINTS = [
5
+ { url: 'https://api.mainnet-beta.solana.com', name: 'Solana Public', priority: 1 },
6
+ { url: 'https://rpc.ankr.com/solana', name: 'Ankr', priority: 2 },
7
+ { url: 'https://solana-api.projectserum.com', name: 'ProjectSerum', priority: 3 },
8
+ ];
9
+ let _endpoints = [...DEFAULT_ENDPOINTS];
10
+ let _currentEndpoint = _endpoints[0];
11
+ export function getEndpoints() {
12
+ return [..._endpoints];
13
+ }
14
+ export function getCurrentEndpoint() {
15
+ return _currentEndpoint;
16
+ }
17
+ export function getRpcUrl() {
18
+ return _currentEndpoint.url;
19
+ }
20
+ export function setEndpoints(endpoints) {
21
+ _endpoints = endpoints.sort((a, b) => a.priority - b.priority);
22
+ _currentEndpoint = _endpoints[0];
23
+ }
24
+ export async function benchmarkEndpoints() {
25
+ const results = [];
26
+ for (const ep of _endpoints) {
27
+ const start = Date.now();
28
+ try {
29
+ await resilientFetch(`${ep.url}`, {
30
+ timeout: 5_000,
31
+ retries: 0,
32
+ method: 'POST',
33
+ headers: { 'Content-Type': 'application/json' },
34
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'getHealth', params: [] }),
35
+ });
36
+ results.push({ endpoint: ep, latency: Date.now() - start });
37
+ }
38
+ catch {
39
+ results.push({ endpoint: ep, latency: Infinity });
40
+ }
41
+ }
42
+ results.sort((a, b) => a.latency - b.latency);
43
+ if (results[0].latency < Infinity) {
44
+ _currentEndpoint = results[0].endpoint;
45
+ }
46
+ }
47
+ export async function rpcCall(method, params = []) {
48
+ const body = JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params });
49
+ const response = await resilientFetch(_currentEndpoint.url, {
50
+ timeout: 15_000,
51
+ retries: 2,
52
+ method: 'POST',
53
+ headers: { 'Content-Type': 'application/json' },
54
+ body,
55
+ });
56
+ const data = await response.json();
57
+ if (data.error) {
58
+ errorAggregator.record({
59
+ name: 'RpcError',
60
+ message: data.error.message || 'Unknown RPC error',
61
+ code: 'RPC_ERROR',
62
+ context: { method, code: data.error.code },
63
+ timestamp: Date.now(),
64
+ recoverable: false,
65
+ });
66
+ throw new Error(data.error.message || 'Unknown RPC error');
67
+ }
68
+ return data.result;
69
+ }
@@ -4,4 +4,3 @@
4
4
  export declare function wireNotify(fn?: (msg: string) => void): void;
5
5
  export declare function safeLog(...args: unknown[]): void;
6
6
  export declare function installSafeLogging(): void;
7
- //# sourceMappingURL=safeLog.d.ts.map
@@ -1,76 +1,75 @@
1
- /**
2
- * src/util/safeLog.ts — Intercepts console output, masks secrets, routes to file
3
- */
1
+
4
2
  import { existsSync, appendFileSync, mkdirSync } from "node:fs";
5
3
  import { join } from "node:path";
6
4
  import { homedir } from "node:os";
7
5
  const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), '.aiaiai');
8
6
  const LOG_DIR = join(AIAIAI_HOME, '.logs');
9
7
  const LOG_FILE = join(LOG_DIR, 'agent.log');
10
- // Patterns that indicate sensitive values
8
+
11
9
  const SENSITIVE_PATTERNS = [
12
- /sk-[a-zA-Z0-9]{20,}/g, // API keys
13
- /[A-Za-z0-9]{32,}/g, // Hex keys
14
- /Bearer\s+[A-Za-z0-9\-._~+/]+/g, // Bearer tokens
15
- /api[_-]?key["\s:=]+["']?[^\s"']+/gi, // Key assignments
16
- /secret["\s:=]+["']?[^\s"']+/gi, // Secrets
10
+ /sk-[a-zA-Z0-9]{20,}/g,
11
+ /[A-Za-z0-9]{32,}/g,
12
+ /Bearer\s+[A-Za-z0-9\-._~+/]+/g,
13
+ /api[_-]?key["\s:=]+["']?[^\s"']+/gi,
14
+ /secret["\s:=]+["']?[^\s"']+/gi,
15
+ /[A-Z0-9]{40,}/g,
17
16
  ];
18
17
  const SENSITIVE_ENV_NAMES = [
19
- 'OPENROUTER_API_KEY', 'ANTHROPIC_API_KEY', 'CRYPTOPANIC_API_KEY',
20
- 'GMGN_API_KEY', 'SOLANA_RPC_URL', 'HELIUS_API_KEY', 'PRIVY_KEY',
18
+ 'OPENROUTER_API_KEY', 'ANTHROPIC_API_KEY', 'CRYPTOPANIC_API_KEY',
19
+ 'GMGN_API_KEY', 'SOLANA_RPC_URL', 'HELIUS_API_KEY', 'PRIVY_KEY',
21
20
  ];
22
21
  const REDACTED = '[REDACTED]';
23
22
  function maskSensitive(text) {
24
- let masked = text;
25
- for (const pattern of SENSITIVE_PATTERNS) {
26
- masked = masked.replace(pattern, (match) => {
27
- // Keep first 4 chars for identification
28
- if (match.length > 8)
29
- return match.slice(0, 4) + '…' + REDACTED;
30
- return REDACTED;
31
- });
32
- }
33
- return masked;
23
+ let masked = text;
24
+ for (const pattern of SENSITIVE_PATTERNS) {
25
+ masked = masked.replace(pattern, (match) => {
26
+
27
+ if (match.length > 8)
28
+ return match.slice(0, 4) + '…' + REDACTED;
29
+ return REDACTED;
30
+ });
31
+ }
32
+ return masked;
34
33
  }
35
34
  function ensureLogDir() {
36
- if (!existsSync(LOG_DIR)) {
37
- mkdirSync(LOG_DIR, { recursive: true, mode: 0o700 });
38
- }
35
+ if (!existsSync(LOG_DIR)) {
36
+ mkdirSync(LOG_DIR, { recursive: true, mode: 0o700 });
37
+ }
39
38
  }
40
39
  function writeToFile(text) {
41
- try {
42
- ensureLogDir();
43
- appendFileSync(LOG_FILE, text + '\n', { encoding: 'utf-8' });
44
- }
45
- catch { /* non-fatal — prevents logging failures from crashing agent */ }
40
+ try {
41
+ ensureLogDir();
42
+ appendFileSync(LOG_FILE, text + '\n', { encoding: 'utf-8' });
43
+ }
44
+ catch { }
46
45
  }
47
46
  export function wireNotify(fn) {
48
- // Wire to notification callback if provided
49
- if (fn) {
50
- // placeholder for notification integration
51
- }
47
+
48
+ if (fn) {
49
+
50
+ }
52
51
  }
53
52
  export function safeLog(...args) {
54
- const raw = args.map(a => typeof a === 'string' ? a : String(a)).join(' ');
55
- const masked = maskSensitive(raw);
56
- const timestamp = new Date().toISOString();
57
- const line = `[${timestamp}] ${masked}`;
58
- try {
59
- writeToFile(line);
60
- }
61
- catch { /* non-fatal */ }
62
- process.stdout.write(line + '\n');
53
+ const raw = args.map(a => typeof a === 'string' ? a : String(a)).join(' ');
54
+ const masked = maskSensitive(raw);
55
+ const timestamp = new Date().toISOString();
56
+ const line = `[${timestamp}] ${masked}`;
57
+ try {
58
+ writeToFile(line);
59
+ }
60
+ catch { }
61
+
62
+ process.stdout.write(line + '\n');
63
63
  }
64
- // Override console methods
64
+
65
65
  export function installSafeLogging() {
66
- console.log = (...args) => safeLog(...args);
67
- console.warn = (...args) => {
68
- const masked = maskSensitive(args.map(String).join(' '));
69
- process.stderr.write(`[WARN] ${masked}\n`);
70
- };
71
- console.error = (...args) => {
72
- const masked = maskSensitive(args.map(String).join(' '));
73
- process.stderr.write(`[ERROR] ${masked}\n`);
74
- };
66
+ console.log = (...args) => safeLog(...args);
67
+ console.warn = (...args) => {
68
+ const masked = maskSensitive(args.map(String).join(' '));
69
+ process.stderr.write(`[WARN] ${masked}\n`);
70
+ };
71
+ console.error = (...args) => {
72
+ const masked = maskSensitive(args.map(String).join(' '));
73
+ process.stderr.write(`[ERROR] ${masked}\n`);
74
+ };
75
75
  }
76
- //# sourceMappingURL=safeLog.js.map
@@ -11,4 +11,3 @@ export declare function resumeAll(): void;
11
11
  * Start the scheduler loop. Returns a stop function.
12
12
  */
13
13
  export declare function startScheduler(): () => void;
14
- //# sourceMappingURL=scheduler.d.ts.map
@@ -1,75 +1,70 @@
1
- /**
2
- * src/util/scheduler.ts — Centralized interval scheduler with pause/resume
3
- */
1
+
4
2
  const MAX_TASKS = 50;
5
3
  const tasks = [];
6
4
  let running = false;
7
5
  export function addTask(name, intervalMs, fn) {
8
- // Replace existing task with same name
9
- const existing = tasks.findIndex(t => t.name === name);
10
- if (existing >= 0) {
11
- tasks[existing] = { name, intervalMs, fn, lastRun: 0, paused: false };
12
- }
13
- else {
14
- if (tasks.length >= MAX_TASKS) {
15
- // Evict oldest non-paused task
16
- const evictIdx = tasks.findIndex(t => !t.paused);
17
- if (evictIdx >= 0)
18
- tasks.splice(evictIdx, 1);
19
- else
20
- return; // All tasks paused, refuse to add
21
- }
22
- tasks.push({ name, intervalMs, fn, lastRun: 0, paused: false });
23
- }
6
+
7
+ const existing = tasks.findIndex(t => t.name === name);
8
+ if (existing >= 0) {
9
+ tasks[existing] = { name, intervalMs, fn, lastRun: 0, paused: false };
10
+ }
11
+ else {
12
+ if (tasks.length >= MAX_TASKS) {
13
+
14
+ const evictIdx = tasks.findIndex(t => !t.paused);
15
+ if (evictIdx >= 0)
16
+ tasks.splice(evictIdx, 1);
17
+ else
18
+ return;
19
+ }
20
+ tasks.push({ name, intervalMs, fn, lastRun: 0, paused: false });
21
+ }
24
22
  }
25
23
  export function removeTask(name) {
26
- const idx = tasks.findIndex(t => t.name === name);
27
- if (idx >= 0)
28
- tasks.splice(idx, 1);
24
+ const idx = tasks.findIndex(t => t.name === name);
25
+ if (idx >= 0)
26
+ tasks.splice(idx, 1);
29
27
  }
30
28
  export function pauseTask(name) {
31
- const task = tasks.find(t => t.name === name);
32
- if (task)
33
- task.paused = true;
29
+ const task = tasks.find(t => t.name === name);
30
+ if (task)
31
+ task.paused = true;
34
32
  }
35
33
  export function resumeTask(name) {
36
- const task = tasks.find(t => t.name === name);
37
- if (task)
38
- task.paused = false;
34
+ const task = tasks.find(t => t.name === name);
35
+ if (task)
36
+ task.paused = false;
39
37
  }
40
38
  export function pauseAll() {
41
- tasks.forEach(t => (t.paused = true));
39
+ tasks.forEach(t => (t.paused = true));
42
40
  }
43
41
  export function resumeAll() {
44
- tasks.forEach(t => (t.paused = false));
42
+ tasks.forEach(t => (t.paused = false));
45
43
  }
46
- /**
47
- * Start the scheduler loop. Returns a stop function.
48
- */
44
+
49
45
  export function startScheduler() {
50
- if (running)
51
- return () => { };
52
- running = true;
53
- const tick = () => {
54
- if (!running)
55
- return;
56
- const now = Date.now();
57
- for (const task of tasks) {
58
- if (task.paused)
59
- continue;
60
- if (now - task.lastRun >= task.intervalMs) {
61
- task.lastRun = now;
62
- try {
63
- task.fn();
64
- }
65
- catch { /* task errors don't crash scheduler */ }
66
- }
67
- }
68
- setTimeout(tick, 1000);
69
- };
70
- tick();
71
- return () => {
72
- running = false;
73
- };
46
+ if (running)
47
+ return () => { };
48
+ running = true;
49
+ const tick = () => {
50
+ if (!running)
51
+ return;
52
+ const now = Date.now();
53
+ for (const task of tasks) {
54
+ if (task.paused)
55
+ continue;
56
+ if (now - task.lastRun >= task.intervalMs) {
57
+ task.lastRun = now;
58
+ try {
59
+ task.fn();
60
+ }
61
+ catch { }
62
+ }
63
+ }
64
+ setTimeout(tick, 1000);
65
+ };
66
+ tick();
67
+ return () => {
68
+ running = false;
69
+ };
74
70
  }
75
- //# sourceMappingURL=scheduler.js.map
@@ -6,4 +6,3 @@ export declare function sendDiscord(message: string): Promise<boolean>;
6
6
  export declare function sendTelegram(message: string): Promise<boolean>;
7
7
  export declare function notify(message: string): Promise<void>;
8
8
  export declare function hasWebhooks(): boolean;
9
- //# sourceMappingURL=webhooks.d.ts.map
@@ -1,75 +1,71 @@
1
- /**
2
- * src/util/webhooks.ts — Discord & Telegram notification webhooks.
3
- * Configure via ~/.aiaiai/.env with WEBHOOK_DISCORD and/or WEBHOOK_TELEGRAM.
4
- */
1
+
5
2
  import { existsSync, readFileSync } from "node:fs";
6
3
  import { join } from "node:path";
7
4
  import { homedir } from "node:os";
8
5
  import { logger } from "./logger.js";
9
6
  const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), ".aiaiai");
10
7
  function getWebhookUrl(service) {
11
- const envFile = join(AIAIAI_HOME, ".env");
12
- if (!existsSync(envFile))
13
- return null;
14
- const content = readFileSync(envFile, "utf-8");
15
- const key = service === "discord" ? "WEBHOOK_DISCORD" : "WEBHOOK_TELEGRAM";
16
- const match = new RegExp(`^${key}=(.+)$`, "m").exec(content);
17
- return match?.[1] ?? null;
8
+ const envFile = join(AIAIAI_HOME, ".env");
9
+ if (!existsSync(envFile))
10
+ return null;
11
+ const content = readFileSync(envFile, "utf-8");
12
+ const key = service === "discord" ? "WEBHOOK_DISCORD" : "WEBHOOK_TELEGRAM";
13
+ const match = new RegExp(`^${key}=(.+)$`, "m").exec(content);
14
+ return match?.[1] ?? null;
18
15
  }
19
16
  export async function sendDiscord(message) {
20
- const url = getWebhookUrl("discord");
21
- if (!url)
22
- return false;
23
- try {
24
- const res = await fetch(url, {
25
- method: "POST",
26
- headers: { "Content-Type": "application/json" },
27
- body: JSON.stringify({ content: `🤖 **AIAIAI Agent**\n${message}` }),
28
- });
29
- return res.ok;
30
- }
31
- catch (error) {
32
- logger.warn("Webhooks", "Discord send failed", { error: error.message });
33
- return false;
34
- }
17
+ const url = getWebhookUrl("discord");
18
+ if (!url)
19
+ return false;
20
+ try {
21
+ const res = await fetch(url, {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/json" },
24
+ body: JSON.stringify({ content: `🤖 **AIAIAI Agent**\n${message}` }),
25
+ });
26
+ return res.ok;
27
+ }
28
+ catch (error) {
29
+ logger.warn("Webhooks", "Discord send failed", { error: error.message });
30
+ return false;
31
+ }
35
32
  }
36
33
  export async function sendTelegram(message) {
37
- const url = getWebhookUrl("telegram");
38
- if (!url)
39
- return false;
40
- // Telegram Bot API format: https://api.telegram.org/bot<TOKEN>/sendMessage
41
- try {
42
- const res = await fetch(url, {
43
- method: "POST",
44
- headers: { "Content-Type": "application/json" },
45
- body: JSON.stringify({
46
- chat_id: extractTelegramChatId(url),
47
- text: `🤖 AIAIAI Agent\n${message}`,
48
- parse_mode: "HTML",
49
- }),
50
- });
51
- return res.ok;
52
- }
53
- catch (error) {
54
- logger.warn("Webhooks", "Telegram send failed", { error: error.message });
55
- return false;
56
- }
34
+ const url = getWebhookUrl("telegram");
35
+ if (!url)
36
+ return false;
37
+
38
+ try {
39
+ const res = await fetch(url, {
40
+ method: "POST",
41
+ headers: { "Content-Type": "application/json" },
42
+ body: JSON.stringify({
43
+ chat_id: extractTelegramChatId(url),
44
+ text: `🤖 AIAIAI Agent\n${message}`,
45
+ parse_mode: "HTML",
46
+ }),
47
+ });
48
+ return res.ok;
49
+ }
50
+ catch (error) {
51
+ logger.warn("Webhooks", "Telegram send failed", { error: error.message });
52
+ return false;
53
+ }
57
54
  }
58
55
  function extractTelegramChatId(url) {
59
- // URL format: https://api.telegram.org/bot<TOKEN>/sendMessage?chat_id=<ID>
60
- const match = /chat_id=([^&]+)/.exec(url);
61
- return match?.[1] ?? "";
56
+
57
+ const match = /chat_id=([^&]+)/.exec(url);
58
+ return match?.[1] ?? "";
62
59
  }
63
60
  export async function notify(message) {
64
- const [discordOk, telegramOk] = await Promise.all([
65
- sendDiscord(message),
66
- sendTelegram(message),
67
- ]);
68
- if (!discordOk && !telegramOk) {
69
- logger.debug("Webhooks", "No webhooks configured or all failed");
70
- }
61
+ const [discordOk, telegramOk] = await Promise.all([
62
+ sendDiscord(message),
63
+ sendTelegram(message),
64
+ ]);
65
+ if (!discordOk && !telegramOk) {
66
+ logger.debug("Webhooks", "No webhooks configured or all failed");
67
+ }
71
68
  }
72
69
  export function hasWebhooks() {
73
- return !!(getWebhookUrl("discord") || getWebhookUrl("telegram"));
70
+ return !!(getWebhookUrl("discord") || getWebhookUrl("telegram"));
74
71
  }
75
- //# sourceMappingURL=webhooks.js.map
@@ -47,4 +47,3 @@ export declare class ActionFeed {
47
47
  getFeesTool(): Promise<ToolResult>;
48
48
  }
49
49
  export declare const actionFeed: ActionFeed;
50
- //# sourceMappingURL=ActionFeed.d.ts.map