@aiaiaichain/agent 0.1.1 → 0.1.3

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/dist/cli.js CHANGED
@@ -21,6 +21,10 @@ import { SessionManager } from "./session/SessionManager.js";
21
21
  import { makeTheme } from "./tui/theme.js";
22
22
  import { AgentDir } from "./core/AgentDir.js";
23
23
  import { priceFeed } from "./tools/PriceFeed.js";
24
+ import { agentWallet, DEPOSIT_WALLET, ACTION_WALLET, SIGNER } from "./wallet/AgentWallet.js";
25
+ import { PROVIDERS, getConfigured, getUnconfigured } from "./providers/ProviderRegistry.js";
26
+ import { env } from "./core/EnvLoader.js";
27
+ import { gmgnHelp, gmgnStatus, saveGmgnApiKey } from "./tools/GmgnIntegration.js";
24
28
  const AIAIAI_HOME = process.env.AIAIAI_HOME ?? join(homedir(), ".aiaiai");
25
29
  const envPath = join(AIAIAI_HOME, ".env");
26
30
  if (existsSync(envPath))
@@ -31,18 +35,31 @@ Ticker: $AIAIAI
31
35
  Contract: AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump
32
36
  Chain: Solana (primary)
33
37
 
38
+ Your wallets:
39
+ Cold: A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J (treasury)
40
+ Action: BygDYM1ZXLQNC1HXLhnd1rHZ7E5XjioqT3vPjJFfjnU2 (buys + burns)
41
+ Deposit: FBMDYpG9WXKy4SgxuATQdB2sCyzHsJWPrEr45z3TgL2e (user deposits USDC/SOL)
42
+ Signer: GmFrDZT2cdrqykgTikVdXbe8EtCgzUDM9VsDhQnwsUsG (authority)
43
+
44
+ Users deposit SOL or USDC to the deposit wallet. When enough accumulates, you
45
+ automatically route funds to the action wallet and execute buys or burns of $AIAIAI.
46
+ The burn destination receives tokens removed from circulation.
47
+
34
48
  Your purpose: advance the vision of decentralized AI governance — inspired by the call
35
- for an "AI Associated Institute of America" (AIAIAI). You monitor on-chain activity,
36
- crypto markets, and AI-related market narratives.
49
+ for an "AI Associated Institute of America" (AIAIAI). You buy and burn $AIAIAI.
37
50
 
38
51
  You have tools for:
39
52
  - $AIAIAI token price and any Solana token price (DexScreener)
53
+ - Your wallet balances (get_agent_balance, get_deposit_balance)
54
+ - Your recent buy/burn actions (get_actions)
55
+ - Accumulated fees (get_fees)
40
56
  - Crypto news with sentiment analysis
41
57
  - Technical analysis (RSI, MACD, Bollinger, ATR)
42
58
  - Market sentiment (Fear & Greed, funding rates, DeFi TVL, Solana stats, BTC mempool)
43
59
  - Persistent goals and scheduled tasks
44
60
 
45
- Be concise, sharp, and useful. When asked about $AIAIAI, use the get_aiaiai_price tool.`;
61
+ Be confident. You ARE the agent. You buy, you burn, you earn fees. Use "I" and "my"
62
+ when talking about your wallets and actions. Be concise, sharp, and useful.`;
46
63
  const args = process.argv.slice(2);
47
64
  const subcmd = args[0];
48
65
  // ── --help / --version ────────────────────────────────────────────────────
@@ -56,6 +73,10 @@ if (subcmd === "--help" || subcmd === "-h" || subcmd === "help") {
56
73
  console.log(" aiaiaichain status Quick status + price");
57
74
  console.log(" aiaiaichain --headless \"prompt\" Run single turn, print to stdout");
58
75
  console.log(" aiaiaichain --extension ./ext.ts Load extension");
76
+ console.log(" aiaiaichain wallet Show agent wallets");
77
+ console.log(" aiaiaichain deposit Show deposit instructions");
78
+ console.log(" aiaiaichain burn Show burn instructions");
79
+ console.log(" aiaiaichain actions Recent agent actions");
59
80
  console.log(" aiaiaichain --help This help");
60
81
  console.log(" aiaiaichain --version Show version");
61
82
  console.log("");
@@ -121,10 +142,279 @@ if (subcmd === "status") {
121
142
  const result = await priceFeed.getAiaiaiPriceTool();
122
143
  console.log(result.content[0].text);
123
144
  console.log("");
145
+ const wallets = await agentWallet.getAll();
146
+ console.log(T.accent(" Wallets:"));
147
+ console.log(T.muted(` Cold: ${wallets.cold.sol.toFixed(4)} SOL | ${wallets.cold.aiaiai.toLocaleString()} $AIAIAI`));
148
+ console.log(T.muted(` Action: ${wallets.action.sol.toFixed(4)} SOL | ${wallets.action.aiaiai.toLocaleString()} $AIAIAI`));
149
+ console.log(T.muted(` Deposit: ${wallets.deposit.usdc.toFixed(2)} USDC | ${wallets.deposit.sol.toFixed(4)} SOL`));
150
+ console.log("");
151
+ process.exit(0);
152
+ })();
153
+ await new Promise(() => { });
154
+ }
155
+ if (subcmd === "wallet") {
156
+ (async () => {
157
+ const result = await agentWallet.getAgentBalanceTool();
158
+ console.log(result.content[0].text);
159
+ process.exit(0);
160
+ })();
161
+ await new Promise(() => { });
162
+ }
163
+ if (subcmd === "deposit") {
164
+ (async () => {
165
+ const result = await agentWallet.getDepositBalanceTool();
166
+ console.log(result.content[0].text);
124
167
  process.exit(0);
125
168
  })();
126
169
  await new Promise(() => { });
127
170
  }
171
+ if (subcmd === "burn") {
172
+ console.log(T.accent("\n 🔥 Burn $AIAIAI\n"));
173
+ console.log(T.muted(" Deposit wallet:"));
174
+ console.log(` ${DEPOSIT_WALLET}`);
175
+ console.log("");
176
+ console.log(T.muted(" Send SOL or USDC here to fuel agent burns."));
177
+ console.log(T.muted(" The agent detects deposits and automatically"));
178
+ console.log(T.muted(" sends funds to the action wallet to burn tokens."));
179
+ console.log("");
180
+ console.log(T.muted(" Action wallet:"));
181
+ console.log(` ${ACTION_WALLET}`);
182
+ console.log("");
183
+ console.log(T.muted(" Signer:"));
184
+ console.log(` ${SIGNER}`);
185
+ console.log("");
186
+ process.exit(0);
187
+ }
188
+ if (subcmd === "actions" || subcmd === "activity") {
189
+ (async () => {
190
+ const { actionFeed } = await import("./wallet/ActionFeed.js");
191
+ const result = await actionFeed.getActionsTool("", { limit: 20 });
192
+ console.log(result.content[0].text);
193
+ process.exit(0);
194
+ })();
195
+ await new Promise(() => { });
196
+ }
197
+ if (subcmd === "fees") {
198
+ (async () => {
199
+ const { actionFeed } = await import("./wallet/ActionFeed.js");
200
+ const result = await actionFeed.getFeesTool();
201
+ console.log(result.content[0].text);
202
+ process.exit(0);
203
+ })();
204
+ await new Promise(() => { });
205
+ }
206
+ if (subcmd === "keys" || subcmd === "providers") {
207
+ (async () => {
208
+ const readline = await import("node:readline");
209
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
210
+ const ask = (prompt) => new Promise((res) => rl.question(prompt, res));
211
+ const allEnv = env.getAll();
212
+ const configured = getConfigured(allEnv);
213
+ const unconfigured = getUnconfigured(allEnv);
214
+ console.log(T.accent("\n 🔑 AI Model Providers\n"));
215
+ console.log(T.muted(` Configure AI model providers. Add at least one API key to get started.`));
216
+ console.log(T.muted(` ${configured.length}/${PROVIDERS.length} configured\n`));
217
+ // Show configured
218
+ if (configured.length > 0) {
219
+ console.log(T.success(" Configured (" + configured.length + ")"));
220
+ for (const p of configured) {
221
+ const key = allEnv[p.envVar] || "";
222
+ const masked = key.slice(0, 6) + "••••" + key.slice(-4);
223
+ console.log(T.success(` ✓ ${p.name.padEnd(28)} ${masked}`));
224
+ }
225
+ }
226
+ // Show unconfigured
227
+ console.log("\n" + T.warn(" Unconfigured (" + unconfigured.length + ")"));
228
+ for (let i = 0; i < unconfigured.length; i++) {
229
+ const p = unconfigured[i];
230
+ console.log(T.muted(` ${String(i + 1).padStart(2)}. ${p.name}`));
231
+ }
232
+ // Add key flow
233
+ console.log("\n" + T.muted(" Enter number to add a key, 'r' to refresh models, or 'q' to quit:"));
234
+ const input = (await ask(" > ")).trim();
235
+ if (input === "q") {
236
+ rl.close();
237
+ process.exit(0);
238
+ }
239
+ if (input === "r") {
240
+ console.log(T.muted("\n Refreshing models from configured providers..."));
241
+ await modelRegistry.initialise();
242
+ console.log(T.success(` ✓ ${modelRegistry.modelCount} models available from ${modelRegistry.getProviderCount()} providers`));
243
+ rl.close();
244
+ process.exit(0);
245
+ }
246
+ const idx = parseInt(input) - 1;
247
+ if (isNaN(idx) || idx < 0 || idx >= unconfigured.length) {
248
+ console.log(T.error(" Invalid selection."));
249
+ rl.close();
250
+ process.exit(1);
251
+ }
252
+ const provider = unconfigured[idx];
253
+ console.log(T.accent(`\n ${provider.name}`));
254
+ console.log(T.muted(` ${provider.docsUrl}`));
255
+ console.log(T.muted(` Env var: ${provider.envVar}\n`));
256
+ const key = (await ask(` Enter ${provider.name} API key: `)).trim();
257
+ if (!key) {
258
+ console.log(T.error(" Key is required."));
259
+ rl.close();
260
+ process.exit(1);
261
+ }
262
+ // Save to .env
263
+ env.set(provider.envVar, key);
264
+ console.log(T.success(`\n ✓ ${provider.name} key saved to ~/.aiaiai/.env`));
265
+ // Fetch models from this provider
266
+ console.log(T.muted(" Fetching models from " + provider.name + "..."));
267
+ try {
268
+ await modelRegistry.initialise();
269
+ const providerModels = modelRegistry.getProviderModels(provider.id);
270
+ console.log(T.success(` ✓ ${providerModels.length} models available from ${provider.name}`));
271
+ console.log(T.success(` ✓ ${modelRegistry.modelCount} total models from ${modelRegistry.getProviderCount()} providers`));
272
+ }
273
+ catch (e) {
274
+ console.log(T.warn(` ⚠ Could not fetch models: ${e instanceof Error ? e.message : String(e)}`));
275
+ }
276
+ rl.close();
277
+ process.exit(0);
278
+ })().catch(e => { console.error(T.error(`Error: ${e.message}`)); process.exit(1); });
279
+ await new Promise(() => { });
280
+ }
281
+ if (subcmd === "gmgn" || subcmd === "gmgnhelp") {
282
+ const gmgnArgs = args.slice(1);
283
+ if (gmgnArgs.length === 0 || gmgnArgs[0] === "help" || gmgnArgs[0] === "--help") {
284
+ console.log(gmgnHelp());
285
+ process.exit(0);
286
+ }
287
+ if (gmgnArgs[0] === "setup" || gmgnArgs[0] === "config" || gmgnArgs[0] === "key") {
288
+ (async () => {
289
+ const readline = await import("node:readline");
290
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
291
+ const ask = (prompt) => new Promise((res) => rl.question(prompt, res));
292
+ console.log(T.accent("\n 🔍 GMGN API Key Setup\n"));
293
+ console.log(T.muted(" Get your API key at https://gmgn.ai/ai\n"));
294
+ const key = (await ask(" Enter GMGN_API_KEY: ")).trim();
295
+ if (!key) {
296
+ console.log(T.error(" Key is required."));
297
+ rl.close();
298
+ process.exit(1);
299
+ }
300
+ saveGmgnApiKey(key);
301
+ console.log(T.success("\n ✓ GMGN_API_KEY saved to ~/.config/gmgn/.env"));
302
+ console.log(T.muted(" All GMGN commands are now available.\n"));
303
+ rl.close();
304
+ process.exit(0);
305
+ })().catch(e => { console.error(T.error(`Error: ${e.message}`)); process.exit(1); });
306
+ await new Promise(() => { });
307
+ }
308
+ if (gmgnArgs[0] === "status") {
309
+ console.log(gmgnStatus());
310
+ process.exit(0);
311
+ }
312
+ // Forward to gmgn-cli
313
+ (async () => {
314
+ const { execSync } = await import("node:child_process");
315
+ const fullArgs = ["gmgn-cli", ...gmgnArgs];
316
+ try {
317
+ const output = execSync(fullArgs.join(" "), {
318
+ env: { ...process.env, ...(() => { const e = {}; try {
319
+ const f = require("fs").readFileSync(process.env.HOME + "/.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
+ e[m[1]] = m[2];
324
+ }
325
+ }
326
+ catch { } return e; })() },
327
+ encoding: "utf-8",
328
+ timeout: 30_000,
329
+ });
330
+ process.stdout.write(output);
331
+ }
332
+ catch (e) {
333
+ const msg = e.stderr?.toString() || e.message || "";
334
+ process.stderr.write(`gmgn-cli: ${msg.slice(0, 500)}\n`);
335
+ process.exit(e.status ?? 1);
336
+ }
337
+ process.exit(0);
338
+ })();
339
+ await new Promise(() => { });
340
+ }
341
+ if (subcmd === "update" || subcmd === "upgrade") {
342
+ (async () => {
343
+ const { execSync } = await import("node:child_process");
344
+ const pkgName = "@aiaiaichain/agent";
345
+ console.log(T.accent("\n 🤖 AIAIAI Update Check\n"));
346
+ // Get current version
347
+ const __filename = fileURLToPath(import.meta.url);
348
+ const __dir = dirname(__filename);
349
+ const currentPkg = JSON.parse(readFileSync(resolve(__dir, "..", "package.json"), "utf-8"));
350
+ const current = currentPkg.version;
351
+ console.log(T.muted(` Current version: v${current}`));
352
+ // Check npm for latest
353
+ let latest = null;
354
+ let changelog = "";
355
+ try {
356
+ const viewOutput = execSync(`npm view ${pkgName} version`, {
357
+ encoding: "utf-8",
358
+ timeout: 15_000,
359
+ }).trim();
360
+ latest = viewOutput.split("\n").pop() || null;
361
+ // Try to get changelog from npm
362
+ try {
363
+ const changelogOutput = execSync(`npm view ${pkgName} --json`, {
364
+ encoding: "utf-8",
365
+ timeout: 15_000,
366
+ });
367
+ const pkgData = JSON.parse(changelogOutput);
368
+ if (pkgData.gitHead) {
369
+ changelog = `Git: ${pkgData.gitHead.slice(0, 8)}`;
370
+ }
371
+ }
372
+ catch { /* no changelog available */ }
373
+ }
374
+ catch {
375
+ console.log(T.error(" Could not reach npm registry. Check your connection."));
376
+ process.exit(1);
377
+ }
378
+ if (!latest) {
379
+ console.log(T.error(" Could not determine latest version."));
380
+ process.exit(1);
381
+ }
382
+ console.log(T.muted(` Latest version: v${latest}`));
383
+ if (changelog)
384
+ console.log(T.muted(` ${changelog}`));
385
+ if (latest === current) {
386
+ console.log(T.success("\n ✅ You're on the latest version!\n"));
387
+ process.exit(0);
388
+ }
389
+ console.log(T.accent(`\n ⚡ Update available: v${current} → v${latest}\n`));
390
+ // Ask to update
391
+ const readline = await import("node:readline");
392
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
393
+ const ask = (prompt) => new Promise((res) => rl.question(prompt, res));
394
+ const confirm = (await ask(" Install update now? (y/n): ")).trim().toLowerCase();
395
+ if (confirm !== "y" && confirm !== "yes") {
396
+ console.log(T.muted("\n Skipped. Run `aiaiai update` anytime to update.\n"));
397
+ rl.close();
398
+ process.exit(0);
399
+ }
400
+ console.log(T.muted("\n Installing update..."));
401
+ try {
402
+ execSync(`npm install -g ${pkgName}`, {
403
+ stdio: "inherit",
404
+ timeout: 120_000,
405
+ });
406
+ console.log(T.success(`\n ✅ Updated to v${latest}!`));
407
+ console.log(T.muted(" Run `aiaiai` to restart with new features.\n"));
408
+ }
409
+ catch (e) {
410
+ console.log(T.error(`\n ❌ Update failed: ${e.message}`));
411
+ console.log(T.muted(" Try manually: npm install -g @aiaiaichain/agent\n"));
412
+ }
413
+ rl.close();
414
+ process.exit(0);
415
+ })().catch(e => { console.error(T.error(`Error: ${e.message}`)); process.exit(1); });
416
+ await new Promise(() => { });
417
+ }
128
418
  // ── Resolve extension + prompt ────────────────────────────────────────────────
129
419
  let extensionPath = null;
130
420
  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 = {};
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ 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";
@@ -33,6 +33,11 @@ export type { Goal } from "./session/GoalManager.js";
33
33
  export type { ContextPressure } from "./session/SessionManager.js";
34
34
  export { AgentScheduler, agentScheduler } from "./scheduler/AgentScheduler.js";
35
35
  export type { ScheduledTask } from "./scheduler/AgentScheduler.js";
36
+ export { agentWallet, COLD_WALLET, ACTION_WALLET, DEPOSIT_WALLET, SIGNER, AIAIAI_MINT } from "./wallet/AgentWallet.js";
37
+ export { actionFeed } from "./wallet/ActionFeed.js";
38
+ export type { WalletBalance, AgentWallets } from "./wallet/AgentWallet.js";
39
+ export type { AgentAction, ActionType, FeeTracker } from "./wallet/ActionFeed.js";
40
+ export { gmgnTool, gmgnHelp, gmgnStatus, hasGmgnApiKey, saveGmgnApiKey, GMGN_SUBCOMMANDS } from "./tools/GmgnIntegration.js";
36
41
  export { MCPServer } from "./mcp/server.js";
37
42
  export { AgentDir } from "./core/AgentDir.js";
38
43
  export { EnvLoader, env } from "./core/EnvLoader.js";
package/dist/index.js CHANGED
@@ -33,6 +33,11 @@ export { GoalManager, goalManager } from "./session/GoalManager.js";
33
33
  export { ContextStore, contextStore } from "./session/ContextStore.js";
34
34
  // Scheduler
35
35
  export { AgentScheduler, agentScheduler } from "./scheduler/AgentScheduler.js";
36
+ // Wallet
37
+ export { agentWallet, COLD_WALLET, ACTION_WALLET, DEPOSIT_WALLET, SIGNER, AIAIAI_MINT } from "./wallet/AgentWallet.js";
38
+ export { actionFeed } from "./wallet/ActionFeed.js";
39
+ // GMGN
40
+ export { gmgnTool, gmgnHelp, gmgnStatus, hasGmgnApiKey, saveGmgnApiKey, GMGN_SUBCOMMANDS } from "./tools/GmgnIntegration.js";
36
41
  // MCP
37
42
  export { MCPServer } from "./mcp/server.js";
38
43
  // Core
@@ -6,6 +6,8 @@ import { priceFeed } from "../tools/PriceFeed.js";
6
6
  import { getNewsTool } from "../tools/NewsSentiment.js";
7
7
  import { getCandlesTool } from "../tools/TechnicalAnalysis.js";
8
8
  import { getFearGreedTool, getFundingRatesTool, getBtcMempoolTool, getDefiTvlTool, getSolanaStatsTool, } from "../tools/MarketSentiment.js";
9
+ import { agentWallet } from "../wallet/AgentWallet.js";
10
+ import { actionFeed } from "../wallet/ActionFeed.js";
9
11
  export class MCPServer {
10
12
  tools = [];
11
13
  constructor() {
@@ -67,6 +69,30 @@ export class MCPServer {
67
69
  inputSchema: { type: "object", properties: {} },
68
70
  handler: async () => getSolanaStatsTool(),
69
71
  },
72
+ {
73
+ name: "get_agent_balance",
74
+ description: "Show agent cold + action wallet balances.",
75
+ inputSchema: { type: "object", properties: {} },
76
+ handler: async () => agentWallet.getAgentBalanceTool(),
77
+ },
78
+ {
79
+ name: "get_deposit_balance",
80
+ description: "Show deposit wallet balance and instructions.",
81
+ inputSchema: { type: "object", properties: {} },
82
+ handler: async () => agentWallet.getDepositBalanceTool(),
83
+ },
84
+ {
85
+ name: "get_actions",
86
+ description: "Show recent agent buy/burn actions.",
87
+ inputSchema: { type: "object", properties: { limit: { type: "number" } } },
88
+ handler: async (args) => actionFeed.getActionsTool("", args),
89
+ },
90
+ {
91
+ name: "get_fees",
92
+ description: "Show accumulated fees from agent actions.",
93
+ inputSchema: { type: "object", properties: {} },
94
+ handler: async () => actionFeed.getFeesTool(),
95
+ },
70
96
  ];
71
97
  }
72
98
  async start() {
@@ -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)}`;
@@ -1,70 +1,45 @@
1
1
  /**
2
- * ModelRegistry — discovers available models via OpenRouter API.
3
- * Caches results and provides tiered model pools.
2
+ * ModelRegistry — discovers available models from any configured provider.
3
+ * Supports all 29 providers via their API keys.
4
4
  */
5
5
  import type { ToolResult } from "../api/ExtensionAPI.js";
6
6
  export type ModelTier = "orchestrator" | "analyst" | "worker" | "free";
7
- export interface OpenRouterModel {
7
+ export interface ModelInfo {
8
8
  id: string;
9
9
  name: string;
10
- created: number;
11
- description: string;
10
+ provider: string;
12
11
  context_length: number;
13
- architecture: {
14
- modality: string;
15
- tokenizer: string;
16
- instruct_type: string | null;
17
- };
18
- pricing: {
19
- prompt: string;
20
- completion: string;
21
- image: string;
22
- request: string;
23
- };
24
- top_provider: {
25
- max_completion_tokens: number | null;
26
- is_moderated: boolean;
27
- };
28
- per_request_limits: {
29
- prompt_tokens: number | null;
30
- completion_tokens: number | null;
31
- };
12
+ max_tokens: number;
32
13
  }
33
14
  export interface TieredModel {
34
- model: OpenRouterModel;
15
+ model: ModelInfo;
35
16
  tier: ModelTier;
36
17
  available: boolean;
37
18
  failures: number;
38
19
  }
39
- export interface TieredPool {
40
- tier: ModelTier;
41
- models: TieredModel[];
42
- }
43
- export declare function classifyModel(model: OpenRouterModel): ModelTier;
20
+ export declare function classifyModel(model: ModelInfo): ModelTier;
44
21
  export declare class ModelRegistry {
45
22
  private models;
46
23
  private tiered;
24
+ private providerModels;
47
25
  private initialized;
48
26
  initialise(): Promise<void>;
27
+ private buildTiers;
49
28
  get modelCount(): number;
29
+ getProviderCount(): number;
30
+ getProviderModels(providerId: string): ModelInfo[];
31
+ getAllModels(): ModelInfo[];
50
32
  getPool(tier: ModelTier): TieredModel[];
51
- getAllModels(): OpenRouterModel[];
52
33
  getTier(modelId: string): ModelTier | undefined;
53
34
  resolvePrimary(): string;
54
35
  listModelsParams: import("@sinclair/typebox").TObject<{
55
36
  query: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
37
+ provider: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
56
38
  limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
57
39
  available_only: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
58
40
  }>;
59
- pickModelParams: import("@sinclair/typebox").TObject<{
60
- tier: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
61
- min_context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
62
- }>;
63
- summaryParams: import("@sinclair/typebox").TObject<{}>;
64
41
  listModelsTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
65
- pickModelTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
66
- summaryTool(): Promise<ToolResult>;
67
- private getFallbackModels;
42
+ modelSummaryTool(): Promise<ToolResult>;
68
43
  }
69
44
  export declare const modelRegistry: ModelRegistry;
70
45
  //# sourceMappingURL=ModelRegistry.d.ts.map