@aiaiaichain/agent 0.1.3 → 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 +2 -2
- package/dist/cli.js +60 -25
- package/dist/core/SystemMonitor.d.ts +35 -0
- package/dist/core/SystemMonitor.js +115 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +7 -1
- package/dist/session/SessionStore.d.ts +45 -0
- package/dist/session/SessionStore.js +123 -0
- package/dist/tools/CrossTools.d.ts +52 -0
- package/dist/tools/CrossTools.js +182 -0
- package/dist/tui/App.d.ts +4 -3
- package/dist/tui/App.js +243 -112
- package/dist/tui/REPL.d.ts +2 -1
- package/dist/tui/REPL.js +189 -15
- package/dist/tui/StatusBar.d.ts +5 -1
- package/dist/tui/StatusBar.js +6 -4
- package/dist/wallet/AgentWallet.d.ts +1 -0
- package/dist/wallet/AgentWallet.js +1 -0
- package/docs/COMMANDS.md +40 -9
- package/docs/README.md +2 -0
- package/package.json +5 -3
- package/scripts/postinstall.js +34 -0
package/dist/tui/App.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* App — root Ink component. Multi-pane TUI with sidebar
|
|
4
|
-
* and
|
|
3
|
+
* App — root Ink component. Multi-pane TUI with sidebar, system monitor,
|
|
4
|
+
* session persistence, and full GMGN command access.
|
|
5
5
|
*/
|
|
6
6
|
import { useState, useCallback, useEffect, useRef, useMemo } from "react";
|
|
7
7
|
import { Box, Text, useApp, useInput } from "ink";
|
|
@@ -16,7 +16,6 @@ import { makeTheme, T, AIAIAI_COLORS } from "./theme.js";
|
|
|
16
16
|
import { AgentRunner } from "../runner/AgentRunner.js";
|
|
17
17
|
import { SessionManager } from "../session/SessionManager.js";
|
|
18
18
|
import { resolveModelConfig } from "../runner/ModelClient.js";
|
|
19
|
-
import { modelRegistry } from "../models/ModelRegistry.js";
|
|
20
19
|
import { priceFeed } from "../tools/PriceFeed.js";
|
|
21
20
|
import { getNewsTool, getNewsParams, newsFeed } from "../tools/NewsSentiment.js";
|
|
22
21
|
import { analyzeTAParams, getCandlesParams, getCandlesTool, fullAnalysis } from "../tools/TechnicalAnalysis.js";
|
|
@@ -25,9 +24,12 @@ import { contextStore } from "../session/ContextStore.js";
|
|
|
25
24
|
import { goalManager } from "../session/GoalManager.js";
|
|
26
25
|
import { memoryStore } from "../session/MemoryStore.js";
|
|
27
26
|
import { agentScheduler } from "../scheduler/AgentScheduler.js";
|
|
27
|
+
import { sessionStore } from "../session/SessionStore.js";
|
|
28
28
|
import { agentWallet, ACTION_WALLET, DEPOSIT_WALLET, SIGNER } from "../wallet/AgentWallet.js";
|
|
29
29
|
import { actionFeed } from "../wallet/ActionFeed.js";
|
|
30
30
|
import { gmgnTool, gmgnToolParams, gmgnHelp, gmgnStatus, gmgnMarketTool, gmgnMarketToolParams } from "../tools/GmgnIntegration.js";
|
|
31
|
+
import { watchTokenTool, watchTokenParams, removeWatchTool, removeWatchParams, listWatchTool, listWatchParams, addAlertTool, addAlertParams, checkAlertsTool, checkAlertsParams, compareTokensTool, compareTokensParams, portfolioTool, portfolioParams, getWatchList as _getWatchList, checkAlerts as _checkAlerts, } from "../tools/CrossTools.js";
|
|
32
|
+
import { systemMonitor } from "../core/SystemMonitor.js";
|
|
31
33
|
function getContextBar(session) {
|
|
32
34
|
if (!session)
|
|
33
35
|
return { pct: 0, bar: "░".repeat(20), color: AIAIAI_COLORS.dim };
|
|
@@ -95,6 +97,11 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
95
97
|
const [fees, setFees] = useState({ buyFees: 0, burnFees: 0, total: 0 });
|
|
96
98
|
const [showModelSelector, setShowModelSelector] = useState(false);
|
|
97
99
|
const [modelSelectorInitialQuery, setModelSelectorInitialQuery] = useState("");
|
|
100
|
+
const [cpu, setCpu] = useState(0);
|
|
101
|
+
const [ram, setRam] = useState(0);
|
|
102
|
+
const [uptime, setUptime] = useState("0m");
|
|
103
|
+
const [apiCalls, setApiCalls] = useState(0);
|
|
104
|
+
const [watchList, setWatchList] = useState([]);
|
|
98
105
|
const runnerRef = useRef(null);
|
|
99
106
|
const sessionRef = useRef(null);
|
|
100
107
|
const sessionCtxRef = useRef(null);
|
|
@@ -120,6 +127,7 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
120
127
|
},
|
|
121
128
|
theme,
|
|
122
129
|
};
|
|
130
|
+
// ── Register ALL tools ──────────────────────────────────────────────────
|
|
123
131
|
function registerBuiltinTools() {
|
|
124
132
|
if (!modelReg)
|
|
125
133
|
return;
|
|
@@ -130,11 +138,11 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
130
138
|
if (costTracker) {
|
|
131
139
|
registry.addTool({ name: "cost_report", label: "Cost Report", description: "Show session and lifetime token usage.", parameters: costTracker.costReportParams, execute: () => costTracker.costReportTool() });
|
|
132
140
|
}
|
|
133
|
-
registry.addTool({ name: "get_aiaiai_price", label: "AIAIAI Price", description: "Get
|
|
134
|
-
registry.addTool({ name: "get_token_price", label: "Token Price", description: "Get
|
|
135
|
-
registry.addTool({ name: "get_news", label: "Get News", description: "Crypto news
|
|
136
|
-
registry.addTool({ name: "get_candles", label: "Get Candles", description: "
|
|
137
|
-
registry.addTool({ name: "analyze_ta", label: "Technical Analysis", description: "
|
|
141
|
+
registry.addTool({ name: "get_aiaiai_price", label: "AIAIAI Price", description: "Get $AIAIAI price, liquidity, MCap, volume.", parameters: priceFeed.getAiaiaiPriceParams, execute: () => priceFeed.getAiaiaiPriceTool() });
|
|
142
|
+
registry.addTool({ name: "get_token_price", label: "Token Price", description: "Get any Solana token price.", parameters: priceFeed.getTokenPriceParams, execute: (id, p) => priceFeed.getTokenPriceTool(id, p) });
|
|
143
|
+
registry.addTool({ name: "get_news", label: "Get News", description: "Crypto news with sentiment.", parameters: getNewsParams, execute: (id, p) => getNewsTool(id, p) });
|
|
144
|
+
registry.addTool({ name: "get_candles", label: "Get Candles", description: "OHLCV from Binance + TA.", parameters: getCandlesParams, execute: (id, p) => getCandlesTool(id, p) });
|
|
145
|
+
registry.addTool({ name: "analyze_ta", label: "Technical Analysis", description: "RSI, MACD, Bollinger, ATR.", parameters: analyzeTAParams, execute: async (_id, p) => {
|
|
138
146
|
const closes = p.prices;
|
|
139
147
|
const candles = closes.map((c, i) => ({ timestamp: 0, open: c, high: p.highs?.[i] ?? c, low: p.lows?.[i] ?? c, close: c, volume: p.volumes?.[i] ?? 0 }));
|
|
140
148
|
const results = fullAnalysis(candles);
|
|
@@ -146,36 +154,37 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
146
154
|
}).join("\n");
|
|
147
155
|
return { content: [{ type: "text", text: `Technical Analysis:\n${text}` }], details: { results, overall_signal: summary?.signal } };
|
|
148
156
|
} });
|
|
149
|
-
registry.addTool({ name: "get_fear_greed", label: "Fear & Greed", description: "Crypto Fear & Greed Index
|
|
150
|
-
registry.addTool({ name: "get_funding_rates", label: "Funding Rates", description: "Binance
|
|
151
|
-
registry.addTool({ name: "get_btc_mempool", label: "BTC Mempool", description: "
|
|
152
|
-
registry.addTool({ name: "get_defi_tvl", label: "DeFi TVL", description: "DeFiLlama TVL
|
|
153
|
-
registry.addTool({ name: "get_solana_stats", label: "Solana Stats", description: "Solana
|
|
157
|
+
registry.addTool({ name: "get_fear_greed", label: "Fear & Greed", description: "Crypto Fear & Greed Index.", parameters: fearGreedParams, execute: () => getFearGreedTool() });
|
|
158
|
+
registry.addTool({ name: "get_funding_rates", label: "Funding Rates", description: "Binance funding rates.", parameters: fundingRatesParams, execute: (id, p) => getFundingRatesTool(id, p) });
|
|
159
|
+
registry.addTool({ name: "get_btc_mempool", label: "BTC Mempool", description: "BTC mempool stats.", parameters: btcMempoolParams, execute: () => getBtcMempoolTool() });
|
|
160
|
+
registry.addTool({ name: "get_defi_tvl", label: "DeFi TVL", description: "DeFiLlama TVL.", parameters: defiTvlParams, execute: (id, p) => getDefiTvlTool(id, p) });
|
|
161
|
+
registry.addTool({ name: "get_solana_stats", label: "Solana Stats", description: "Solana epoch, slot, SOL price.", parameters: solanaStatsParams, execute: () => getSolanaStatsTool() });
|
|
162
|
+
registry.addTool({ name: "get_agent_balance", label: "Agent Balance", description: "Cold + action wallet balances.", parameters: agentWallet.getAgentBalanceParams, execute: () => agentWallet.getAgentBalanceTool() });
|
|
163
|
+
registry.addTool({ name: "get_deposit_balance", label: "Deposit Balance", description: "Deposit wallet + instructions.", parameters: agentWallet.getDepositBalanceParams, execute: () => agentWallet.getDepositBalanceTool() });
|
|
164
|
+
registry.addTool({ name: "get_actions", label: "Agent Actions", description: "Recent buy/burn actions.", parameters: actionFeed.getActionsParams, execute: (id, p) => actionFeed.getActionsTool(id, p) });
|
|
165
|
+
registry.addTool({ name: "get_fees", label: "Agent Fees", description: "Accumulated fees.", parameters: actionFeed.getFeesParams, execute: () => actionFeed.getFeesTool() });
|
|
154
166
|
registry.addTool({ name: "read_task_context", label: "Read Task Context", description: "Read saved task context.", parameters: Type.Object({ taskId: Type.String({ description: "Task ID" }) }), execute: (id, p) => contextStore.readContextTool(id, p) });
|
|
155
167
|
registry.addTool({ name: "list_tasks", label: "List Tasks", description: "List saved task contexts.", parameters: Type.Object({}), execute: () => contextStore.listTasksTool() });
|
|
156
|
-
registry.addTool({ name: "set_goal", label: "Set Goal", description: "Set a persistent
|
|
168
|
+
registry.addTool({ name: "set_goal", label: "Set Goal", description: "Set a persistent goal.", parameters: goalManager.setGoalParams, execute: (id, p) => goalManager.setGoalTool(id, p) });
|
|
157
169
|
registry.addTool({ name: "complete_goal", label: "Complete Goal", description: "Mark a goal complete.", parameters: goalManager.completeGoalParams, execute: (id, p) => goalManager.completeGoalTool(id, p) });
|
|
158
170
|
registry.addTool({ name: "list_goals", label: "List Goals", description: "List goals.", parameters: goalManager.listGoalsParams, execute: (id, p) => goalManager.listGoalsTool(id, p) });
|
|
159
171
|
registry.addTool({ name: "add_goal_note", label: "Add Goal Note", description: "Add a note to a goal.", parameters: goalManager.addGoalNoteParams, execute: (id, p) => goalManager.addGoalNoteTool(id, p) });
|
|
160
|
-
registry.addTool({ name: "schedule_task", label: "Schedule Task", description: "Schedule a recurring
|
|
172
|
+
registry.addTool({ name: "schedule_task", label: "Schedule Task", description: "Schedule a recurring task.", parameters: agentScheduler.addTaskParams, execute: (id, p) => agentScheduler.addTaskTool(id, p) });
|
|
161
173
|
registry.addTool({ name: "list_schedule", label: "List Schedule", description: "List scheduled tasks.", parameters: agentScheduler.listTasksParams, execute: (id, p) => agentScheduler.listTasksTool(id, p) });
|
|
162
174
|
registry.addTool({ name: "remove_schedule", label: "Remove Schedule", description: "Remove a scheduled task.", parameters: agentScheduler.removeTaskParams, execute: (id, p) => agentScheduler.removeTaskTool(id, p) });
|
|
163
175
|
// GMGN tools
|
|
164
|
-
registry.addTool({ name: "gmgn", label: "GMGN Token Research", description: "
|
|
165
|
-
registry.addTool({ name: "gmgn_market", label: "GMGN Market Data", description: "Market data
|
|
166
|
-
//
|
|
167
|
-
registry.addTool({ name: "
|
|
168
|
-
registry.addTool({ name: "
|
|
169
|
-
registry.addTool({ name: "
|
|
170
|
-
registry.addTool({ name: "
|
|
176
|
+
registry.addTool({ name: "gmgn", label: "GMGN Token Research", description: "Full GMGN access: token info, security, holders, traders, tracking, market data.", parameters: gmgnToolParams, execute: (id, p) => gmgnTool(id, p) });
|
|
177
|
+
registry.addTool({ name: "gmgn_market", label: "GMGN Market Data", description: "Market data: trending, trenches, kline, signals.", parameters: gmgnMarketToolParams, execute: (id, p) => gmgnMarketTool(id, p) });
|
|
178
|
+
// Cross tools
|
|
179
|
+
registry.addTool({ name: "watch_token", label: "Watch Token", description: "Add token to watch list.", parameters: watchTokenParams, execute: (id, p) => watchTokenTool(id, p) });
|
|
180
|
+
registry.addTool({ name: "unwatch_token", label: "Unwatch Token", description: "Remove token from watch list.", parameters: removeWatchParams, execute: (id, p) => removeWatchTool(id, p) });
|
|
181
|
+
registry.addTool({ name: "watch_list", label: "Watch List", description: "Show watched tokens.", parameters: listWatchParams, execute: () => listWatchTool() });
|
|
182
|
+
registry.addTool({ name: "add_alert", label: "Price Alert", description: "Set a price alert.", parameters: addAlertParams, execute: (id, p) => addAlertTool(id, p) });
|
|
183
|
+
registry.addTool({ name: "check_alerts", label: "Check Alerts", description: "List active alerts.", parameters: checkAlertsParams, execute: () => checkAlertsTool() });
|
|
184
|
+
registry.addTool({ name: "compare_tokens", label: "Compare Tokens", description: "Side-by-side token comparison.", parameters: compareTokensParams, execute: (id, p) => compareTokensTool(id, p) });
|
|
185
|
+
registry.addTool({ name: "portfolio", label: "Portfolio", description: "Wallet portfolio analysis.", parameters: portfolioParams, execute: (id, p) => portfolioTool(id, p) });
|
|
171
186
|
}
|
|
172
|
-
|
|
173
|
-
useEffect(() => {
|
|
174
|
-
onModelSelectorReady?.((initialQuery) => {
|
|
175
|
-
setModelSelectorInitialQuery(initialQuery ?? "");
|
|
176
|
-
setShowModelSelector(true);
|
|
177
|
-
});
|
|
178
|
-
}, [onModelSelectorReady]);
|
|
187
|
+
// ── Main effect: setup + intervals ──────────────────────────────────────
|
|
179
188
|
useEffect(() => {
|
|
180
189
|
registerBuiltinTools();
|
|
181
190
|
// Initial price fetch
|
|
@@ -201,8 +210,11 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
201
210
|
setSidebarNews(report.items.slice(0, 6).map(i => ({ title: i.title, sentiment: i.sentiment ?? 0, source: i.source })));
|
|
202
211
|
setNewsBadge(newsFeed.statusBadge());
|
|
203
212
|
}).catch(() => { });
|
|
213
|
+
// Load watch list
|
|
214
|
+
setWatchList(_getWatchList());
|
|
215
|
+
// Scheduler
|
|
204
216
|
agentScheduler.start((task) => {
|
|
205
|
-
push({ role: "system", content: T.muted(`⏰ Scheduled
|
|
217
|
+
push({ role: "system", content: T.muted(`⏰ Scheduled: "${task.name}"`) });
|
|
206
218
|
if (!disabled && runnerRef.current) {
|
|
207
219
|
setDisabled(true);
|
|
208
220
|
setStreaming("");
|
|
@@ -217,6 +229,14 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
217
229
|
if (p.priceUsd)
|
|
218
230
|
setPriceBadge(`$${parseFloat(p.priceUsd).toFixed(6)}`);
|
|
219
231
|
actionFeed.setPrice(parseFloat(p.priceUsd || "0.0004"));
|
|
232
|
+
systemMonitor.trackApiCall();
|
|
233
|
+
// Check alerts
|
|
234
|
+
if (p.priceUsd) {
|
|
235
|
+
const triggered = _checkAlerts(parseFloat(p.priceUsd), "AIAIAI");
|
|
236
|
+
for (const alert of triggered) {
|
|
237
|
+
notify(`🔔 Alert triggered: ${alert.type} $${alert.price} — $AIAIAI is now $${p.priceUsd}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
220
240
|
}).catch(() => { });
|
|
221
241
|
if (costTracker)
|
|
222
242
|
setCostBadge(costTracker.statusLine());
|
|
@@ -240,7 +260,21 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
240
260
|
setNewsBadge(newsFeed.statusBadge());
|
|
241
261
|
}).catch(() => { });
|
|
242
262
|
}, 300_000);
|
|
243
|
-
|
|
263
|
+
// System monitor interval (10s)
|
|
264
|
+
const sysInterval = setInterval(() => {
|
|
265
|
+
const stats = systemMonitor.getStats();
|
|
266
|
+
setCpu(stats.cpuPercent);
|
|
267
|
+
setRam(stats.ramPercent);
|
|
268
|
+
setUptime(stats.uptime);
|
|
269
|
+
setApiCalls(systemMonitor.resetApiCounter());
|
|
270
|
+
}, 10_000);
|
|
271
|
+
// Session auto-save (30s)
|
|
272
|
+
sessionStore.startAutoSave(() => messages);
|
|
273
|
+
sessionStore.setCurrentId(sessionId);
|
|
274
|
+
const saveInterval = setInterval(() => {
|
|
275
|
+
if (messages.length > 0)
|
|
276
|
+
sessionStore.save(messages);
|
|
277
|
+
}, 30_000);
|
|
244
278
|
const session = new SessionManager();
|
|
245
279
|
session.setSystemPrompt(registry.getSystemPrompt() || systemPrompt || "You are AIAIAI Chain Agent.");
|
|
246
280
|
sessionRef.current = session;
|
|
@@ -304,9 +338,13 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
304
338
|
if (sessionCtxRef.current)
|
|
305
339
|
registry.fireHook("session_end", sessionCtxRef.current).catch(() => { });
|
|
306
340
|
agentScheduler.stop();
|
|
341
|
+
sessionStore.stopAutoSave();
|
|
342
|
+
if (messages.length > 0)
|
|
343
|
+
sessionStore.save(messages);
|
|
307
344
|
clearInterval(priceInterval);
|
|
308
345
|
clearInterval(walletInterval);
|
|
309
346
|
clearInterval(newsInterval);
|
|
347
|
+
clearInterval(sysInterval);
|
|
310
348
|
clearInterval(saveInterval);
|
|
311
349
|
costTracker?.saveLifetime();
|
|
312
350
|
};
|
|
@@ -314,10 +352,13 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
314
352
|
useInput((_input, key) => {
|
|
315
353
|
if (key.ctrl && _input === "c") {
|
|
316
354
|
push({ role: "system", content: T.muted("Goodbye 🤖") });
|
|
355
|
+
if (messages.length > 0)
|
|
356
|
+
sessionStore.save(messages);
|
|
317
357
|
costTracker?.saveLifetime();
|
|
318
358
|
setTimeout(exit, 200);
|
|
319
359
|
}
|
|
320
360
|
});
|
|
361
|
+
// ── Submit handler ─────────────────────────────────────────────────────
|
|
321
362
|
const handleSubmit = useCallback(async (raw) => {
|
|
322
363
|
const input = raw.trim();
|
|
323
364
|
if (!input)
|
|
@@ -326,16 +367,157 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
326
367
|
const [cmd, ...rest] = input.slice(1).split(" ");
|
|
327
368
|
const args = rest.join(" ");
|
|
328
369
|
if (cmd === "exit" || cmd === "quit") {
|
|
329
|
-
|
|
370
|
+
if (messages.length > 0)
|
|
371
|
+
sessionStore.save(messages);
|
|
330
372
|
costTracker?.saveLifetime();
|
|
373
|
+
push({ role: "system", content: T.muted("Goodbye 🤖") });
|
|
331
374
|
setTimeout(exit, 200);
|
|
332
375
|
return;
|
|
333
376
|
}
|
|
334
377
|
if (cmd === "help") {
|
|
335
|
-
|
|
336
|
-
|
|
378
|
+
notify("Commands:\n/token info|security|holders|traders\n/track kol|smartmoney|follow-wallet\n/market kline|trending|trenches|signal\n/watch /unwatch /watchlist /alerts /alert /compare /portfolio\n/keys /wallet /deposit /burn /actions /fees\n/models /cost /goals /schedule /update\n/sessions /resume /memory /clear /exit\n\nTab to auto-complete, ↑↓ for history, Shift+Enter for multi-line");
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
// ── GMGN direct commands ──────────────────────────────────────────
|
|
382
|
+
if (cmd === "token") {
|
|
383
|
+
// /token info --chain sol --address <addr>
|
|
384
|
+
const parts = args.split(" ");
|
|
385
|
+
const subcmd = parts[0];
|
|
386
|
+
if (!subcmd || subcmd === "help") {
|
|
387
|
+
notify("Token commands:\n/token info --chain <sol|bsc|base|eth> --address <addr>\n/token security --chain <chain> --address <addr>\n/token holders --chain <chain> --address <addr>\n/token traders --chain <chain> --address <addr>");
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const chain = parts[parts.indexOf("--chain") + 1] || "sol";
|
|
391
|
+
const address = parts[parts.indexOf("--address") + 1];
|
|
392
|
+
if (!address && subcmd !== "help") {
|
|
393
|
+
notify(T.error("--address is required"));
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const result = await gmgnTool("", { subcommand: subcmd, chain, address });
|
|
397
|
+
notify(result.content[0].text);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (cmd === "track") {
|
|
401
|
+
// /track kol --chain sol
|
|
402
|
+
const parts = args.split(" ");
|
|
403
|
+
const subcmd = parts[0];
|
|
404
|
+
if (!subcmd || subcmd === "help") {
|
|
405
|
+
notify("Track commands:\n/track kol --chain <sol|bsc|base|eth>\n/track smartmoney --chain <chain>\n/track follow-wallet --chain <chain>");
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const chain = parts[parts.indexOf("--chain") + 1] || "sol";
|
|
409
|
+
const result = await gmgnTool("", { subcommand: `track ${subcmd}`, chain, limit: 10 });
|
|
410
|
+
notify(result.content[0].text);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
if (cmd === "market") {
|
|
414
|
+
// /market kline --chain sol --address <addr> --resolution 1h
|
|
415
|
+
const parts = args.split(" ");
|
|
416
|
+
const subcmd = parts[0];
|
|
417
|
+
if (!subcmd || subcmd === "help") {
|
|
418
|
+
notify("Market commands:\n/market kline --chain <chain> --address <addr> --resolution <1h|4h|1d>\n/market trending --chain <chain> --interval <1h|6h|24h>\n/market trenches --chain <chain> --type <new_creation|near_completion|completed>\n/market signal --chain <sol|bsc>");
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const chain = parts[parts.indexOf("--chain") + 1] || "sol";
|
|
422
|
+
const address = parts[parts.indexOf("--address") + 1];
|
|
423
|
+
const resolution = parts[parts.indexOf("--resolution") + 1];
|
|
424
|
+
const interval = parts[parts.indexOf("--interval") + 1];
|
|
425
|
+
const trenchesType = parts[parts.indexOf("--type") + 1];
|
|
426
|
+
const toolParams = { subcommand: `market ${subcmd}`, chain };
|
|
427
|
+
if (address)
|
|
428
|
+
toolParams.address = address;
|
|
429
|
+
if (resolution)
|
|
430
|
+
toolParams.resolution = resolution;
|
|
431
|
+
if (interval)
|
|
432
|
+
toolParams.interval = interval;
|
|
433
|
+
if (trenchesType)
|
|
434
|
+
toolParams.type = trenchesType;
|
|
435
|
+
const result = await gmgnTool("", toolParams);
|
|
436
|
+
notify(result.content[0].text);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
// ── Cross tools ────────────────────────────────────────────────────
|
|
440
|
+
if (cmd === "watch") {
|
|
441
|
+
const result = await watchTokenTool("", { address: args || "AVPJS61gZmWKtaEpb7qYPKo8Fk2xQUsayYQxPiPMpump" });
|
|
442
|
+
setWatchList(_getWatchList());
|
|
443
|
+
notify(result.content[0].text);
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (cmd === "unwatch") {
|
|
447
|
+
const result = await removeWatchTool("", { address: args });
|
|
448
|
+
setWatchList(_getWatchList());
|
|
449
|
+
notify(result.content[0].text);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
if (cmd === "watchlist") {
|
|
453
|
+
const result = await listWatchTool();
|
|
454
|
+
notify(result.content[0].text);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
if (cmd === "alerts") {
|
|
458
|
+
const result = await checkAlertsTool();
|
|
459
|
+
notify(result.content[0].text);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (cmd === "alert") {
|
|
463
|
+
// /alert above 0.001 AIAIAI
|
|
464
|
+
const parts = args.split(" ");
|
|
465
|
+
const type = parts[0];
|
|
466
|
+
const price = parseFloat(parts[1]);
|
|
467
|
+
if (!type || isNaN(price)) {
|
|
468
|
+
notify(T.error("Usage: /alert above|below <price>"));
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
const result = await addAlertTool("", { token: "AIAIAI", type, price });
|
|
472
|
+
notify(result.content[0].text);
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (cmd === "compare") {
|
|
476
|
+
// /compare <addr1> <addr2>
|
|
477
|
+
const parts = args.split(" ");
|
|
478
|
+
if (parts.length < 2) {
|
|
479
|
+
notify(T.error("Usage: /compare <address1> <address2>"));
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
const result = await compareTokensTool("", { address1: parts[0], address2: parts[1] });
|
|
483
|
+
notify(result.content[0].text);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
if (cmd === "portfolio") {
|
|
487
|
+
const addr = args || "A11iZoqEt6hU7HyggqC67ee4AtYmaJjwKCvJLerJRV2J";
|
|
488
|
+
const result = await portfolioTool("", { address: addr });
|
|
489
|
+
notify(result.content[0].text);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
// ── Session management ─────────────────────────────────────────────
|
|
493
|
+
if (cmd === "sessions") {
|
|
494
|
+
const sessions = sessionStore.list();
|
|
495
|
+
if (sessions.length === 0) {
|
|
496
|
+
notify("No saved sessions.");
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const lines = sessions.slice(0, 10).map((s, i) => ` ${i + 1}. ${s.title} (${s.messageCount} msgs, ${new Date(s.updatedAt).toLocaleDateString()})`);
|
|
500
|
+
notify(`Recent Sessions:\n${lines.join("\n")}\n\nUse /resume <number> to resume.`);
|
|
337
501
|
return;
|
|
338
502
|
}
|
|
503
|
+
if (cmd === "resume") {
|
|
504
|
+
const sessions = sessionStore.list();
|
|
505
|
+
const idx = parseInt(args) - 1;
|
|
506
|
+
if (isNaN(idx) || idx < 0 || idx >= sessions.length) {
|
|
507
|
+
notify(T.error("Invalid session number."));
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
const session = sessionStore.load(sessions[idx].id);
|
|
511
|
+
if (!session) {
|
|
512
|
+
notify(T.error("Session not found."));
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
setMessages(session.messages);
|
|
516
|
+
sessionStore.setCurrentId(session.id);
|
|
517
|
+
notify(`Resumed: ${session.title} (${session.messages.length} messages)`);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
// ── Standard commands ───────────────────────────────────────────────
|
|
339
521
|
if (cmd === "price") {
|
|
340
522
|
const result = await priceFeed.getAiaiaiPriceTool();
|
|
341
523
|
notify(result.content[0].text);
|
|
@@ -384,20 +566,7 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
384
566
|
return;
|
|
385
567
|
}
|
|
386
568
|
if (cmd === "burn") {
|
|
387
|
-
notify([
|
|
388
|
-
"🔥 Burn $AIAIAI",
|
|
389
|
-
"",
|
|
390
|
-
`Deposit wallet: ${DEPOSIT_WALLET}`,
|
|
391
|
-
`Send SOL or USDC here to fuel agent burns.`,
|
|
392
|
-
"",
|
|
393
|
-
`The agent detects deposits and automatically`,
|
|
394
|
-
`sends funds to the action wallet to burn tokens.`,
|
|
395
|
-
"",
|
|
396
|
-
`Action wallet: ${ACTION_WALLET}`,
|
|
397
|
-
`Signer: ${SIGNER}`,
|
|
398
|
-
"",
|
|
399
|
-
`Burn destination: tokens are removed from circulation.`,
|
|
400
|
-
].join("\n"));
|
|
569
|
+
notify(["🔥 Burn $AIAIAI", "", `Deposit: ${DEPOSIT_WALLET}`, "Send SOL or USDC here.", "", `Action: ${ACTION_WALLET}`, `Signer: ${SIGNER}`].join("\n"));
|
|
401
570
|
return;
|
|
402
571
|
}
|
|
403
572
|
if (cmd === "actions" || cmd === "activity") {
|
|
@@ -410,6 +579,10 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
410
579
|
notify(result.content[0].text);
|
|
411
580
|
return;
|
|
412
581
|
}
|
|
582
|
+
if (cmd === "keys" || cmd === "providers") {
|
|
583
|
+
notify("Switch to CLI for key management:\n aiaiai keys");
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
413
586
|
if (cmd === "goals" || cmd === "goal") {
|
|
414
587
|
const subCmd = args.trim().split(" ")[0];
|
|
415
588
|
if (subCmd === "add") {
|
|
@@ -441,29 +614,23 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
441
614
|
notify(result.content[0].text);
|
|
442
615
|
return;
|
|
443
616
|
}
|
|
444
|
-
if (cmd === "
|
|
445
|
-
|
|
446
|
-
if (pending) {
|
|
447
|
-
pending(true);
|
|
448
|
-
push({ role: "system", content: T.success("✅ Tool approved.") });
|
|
449
|
-
}
|
|
450
|
-
else
|
|
451
|
-
notify(T.error("No pending approval."));
|
|
617
|
+
if (cmd === "update" || cmd === "upgrade") {
|
|
618
|
+
notify("Switch to CLI:\n aiaiai update");
|
|
452
619
|
return;
|
|
453
620
|
}
|
|
454
|
-
if (cmd === "
|
|
455
|
-
const
|
|
456
|
-
if (
|
|
457
|
-
|
|
458
|
-
|
|
621
|
+
if (cmd === "memory" && args.trim()) {
|
|
622
|
+
const results = memoryStore.search(args.trim(), 8);
|
|
623
|
+
if (results.length === 0) {
|
|
624
|
+
notify(T.muted("No memories found."));
|
|
625
|
+
return;
|
|
459
626
|
}
|
|
460
|
-
|
|
461
|
-
|
|
627
|
+
const lines = results.map(r => `[${new Date(r.ts).toLocaleDateString()} ${r.role}] ${r.content.slice(0, 120)}`);
|
|
628
|
+
notify(`Memory: "${args.trim()}"\n${lines.join("\n")}`);
|
|
462
629
|
return;
|
|
463
630
|
}
|
|
464
631
|
if (cmd === "gmgn" || cmd === "gmgnhelp") {
|
|
465
632
|
const gmgnArgs = rest.join(" ");
|
|
466
|
-
if (!gmgnArgs || gmgnArgs === "help"
|
|
633
|
+
if (!gmgnArgs || gmgnArgs === "help") {
|
|
467
634
|
notify(gmgnHelp());
|
|
468
635
|
return;
|
|
469
636
|
}
|
|
@@ -471,58 +638,19 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
471
638
|
notify(gmgnStatus());
|
|
472
639
|
return;
|
|
473
640
|
}
|
|
474
|
-
if (gmgnArgs.startsWith("setup")
|
|
475
|
-
notify("
|
|
641
|
+
if (gmgnArgs.startsWith("setup")) {
|
|
642
|
+
notify("Run in CLI: aiaiai gmgn setup");
|
|
476
643
|
return;
|
|
477
644
|
}
|
|
478
|
-
|
|
479
|
-
const result = await gmgnTool("", { subcommand: gmgnArgs.split(" ")[0], chain: "sol", ...Object.fromEntries(gmgnArgs.split(" ").slice(1).reduce((acc, val, i) => { if (i % 2 === 0)
|
|
480
|
-
acc.push([val]);
|
|
481
|
-
else
|
|
482
|
-
acc[acc.length - 1].push(val); return acc; }, []).map(([k, v]) => [k, v || true])) });
|
|
645
|
+
const result = await gmgnTool("", { subcommand: gmgnArgs.split(" ")[0], chain: "sol" });
|
|
483
646
|
notify(result.content[0].text);
|
|
484
647
|
return;
|
|
485
648
|
}
|
|
486
649
|
if (cmd === "gmgnmarket" || cmd === "market") {
|
|
487
|
-
const
|
|
488
|
-
const result = await gmgnMarketTool("", { query: query || "trending", chain: "sol" });
|
|
650
|
+
const result = await gmgnMarketTool("", { query: args || "trending", chain: "sol" });
|
|
489
651
|
notify(result.content[0].text);
|
|
490
652
|
return;
|
|
491
653
|
}
|
|
492
|
-
if (cmd === "update" || cmd === "upgrade") {
|
|
493
|
-
notify([
|
|
494
|
-
"🤖 AIAIAI Update",
|
|
495
|
-
"",
|
|
496
|
-
"Switch to CLI to check for updates:",
|
|
497
|
-
" aiaiai update",
|
|
498
|
-
"",
|
|
499
|
-
"This will check npm for the latest version",
|
|
500
|
-
"and install it if available.",
|
|
501
|
-
].join("\n"));
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
if (cmd === "keys" || cmd === "providers") {
|
|
505
|
-
notify([
|
|
506
|
-
"🔑 AI Model Providers",
|
|
507
|
-
"",
|
|
508
|
-
"Switch to CLI to manage keys:", " aiaiaichain keys",
|
|
509
|
-
"",
|
|
510
|
-
"Or use /models to see available models.",
|
|
511
|
-
`\nProviders: ${modelRegistry.getProviderCount()} configured`,
|
|
512
|
-
`Models: ${modelRegistry.modelCount} available`,
|
|
513
|
-
].join("\n"));
|
|
514
|
-
return;
|
|
515
|
-
}
|
|
516
|
-
if (cmd === "memory" && args.trim()) {
|
|
517
|
-
const results = memoryStore.search(args.trim(), 8);
|
|
518
|
-
if (results.length === 0) {
|
|
519
|
-
notify(T.muted("No memories found for: " + args.trim()));
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
const lines = results.map(r => `[${new Date(r.ts).toLocaleDateString()} ${r.role}] ${r.content.slice(0, 120)}`);
|
|
523
|
-
notify(`Memory search: "${args.trim()}"\n${lines.join("\n")}`);
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
654
|
const def = registry.getCommand(cmd);
|
|
527
655
|
if (!def) {
|
|
528
656
|
notify(T.error(`Unknown: /${cmd} — try /help`));
|
|
@@ -552,6 +680,7 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
552
680
|
notify(T.error(`Error: ${e.message}`));
|
|
553
681
|
}
|
|
554
682
|
}, [registry, exit, push, notify, uiCtx, modelReg, costTracker]);
|
|
683
|
+
// ── Model selector ─────────────────────────────────────────────────────
|
|
555
684
|
const handleModelSelect = useCallback((modelId) => {
|
|
556
685
|
setShowModelSelector(false);
|
|
557
686
|
try {
|
|
@@ -584,18 +713,20 @@ export function App({ registry, systemPrompt, chain: initialChain = "solana", mo
|
|
|
584
713
|
}, [modelReg]);
|
|
585
714
|
const ctx = getContextBar(sessionRef.current);
|
|
586
715
|
const statusLine = [costBadge, newsBadge, ...Object.values(statusBadges)].filter(Boolean).join(" ") || null;
|
|
587
|
-
const changeColor = (pct) => pct > 0 ? AIAIAI_COLORS.success : pct < 0 ? AIAIAI_COLORS.error : AIAIAI_COLORS.muted;
|
|
588
716
|
const SIDEBAR_W = 44;
|
|
589
717
|
const SIDEBAR_MIN = 38;
|
|
590
|
-
const
|
|
718
|
+
const changeColor = (pct) => pct > 0 ? AIAIAI_COLORS.success : pct < 0 ? AIAIAI_COLORS.error : AIAIAI_COLORS.muted;
|
|
719
|
+
const actionIcon = (type) => type === "buy" ? "↗" : type === "burn" ? "🔥" : "→";
|
|
591
720
|
if (showModelSelector) {
|
|
592
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusBar, { model: modelName, chain: chain, price: priceBadge, toolRunning: toolRunning, connected: true, statusLine: statusLine }), _jsx(ModelSelector, { models: modelList, currentModelId: process.env.DEFAULT_MODEL ?? "", onSelect: handleModelSelect, onCancel: handleModelCancel, initialQuery: modelSelectorInitialQuery })] }));
|
|
721
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusBar, { model: modelName, chain: chain, price: priceBadge, toolRunning: toolRunning, connected: true, statusLine: statusLine, cpu: cpu, ram: ram, uptime: uptime, apiCalls: apiCalls }), _jsx(ModelSelector, { models: modelList, currentModelId: process.env.DEFAULT_MODEL ?? "", onSelect: handleModelSelect, onCancel: handleModelCancel, initialQuery: modelSelectorInitialQuery })] }));
|
|
593
722
|
}
|
|
594
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusBar, { model: modelName, chain: chain, price: priceBadge, toolRunning: toolRunning, connected: true, statusLine: statusLine }), _jsxs(Box, { flexDirection: "row", flexGrow: 1, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "column", width: SIDEBAR_W, minWidth: SIDEBAR_MIN, flexShrink: 0, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.accent, paddingX: 1, children: [_jsx(Text, { bold: true, color: AIAIAI_COLORS.accent, children: "\uD83E\uDD16 $AIAIAI" }), aiaiPrice ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: changeColor(aiaiPrice.change), children: [aiaiPrice.priceUsd ? `$${parseFloat(aiaiPrice.priceUsd).toFixed(8)}` : "N/A", " ", aiaiPrice.change > 0 ? "▲" : aiaiPrice.change < 0 ? "▼" : "─", Math.abs(aiaiPrice.change).toFixed(1), "%"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["MCap: ", aiaiPrice.mcap ? `$${(aiaiPrice.mcap / 1000).toFixed(1)}k` : "N/A"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Liq: $", (aiaiPrice.liq / 1000).toFixed(1), "k"] })] })) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Loading\u2026" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\uD83D\uDCBC Wallets" }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Cold: ", coldBalance.sol.toFixed(2), " SOL"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" AIAIAI: ", coldBalance.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 0 })] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Action: ", actionBalance.sol.toFixed(2), " SOL"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" AIAIAI: ", actionBalance.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 0 })] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Deposit: ", depositBalance.usdc.toFixed(2), " USDC"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" SOL: ", depositBalance.sol.toFixed(2)] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\u26A1 Actions" }), recentActions.length > 0 ? recentActions.map((a, i) => {
|
|
723
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatusBar, { model: modelName, chain: chain, price: priceBadge, toolRunning: toolRunning, connected: true, statusLine: statusLine, cpu: cpu, ram: ram, uptime: uptime, apiCalls: apiCalls }), _jsxs(Box, { flexDirection: "row", flexGrow: 1, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "column", width: SIDEBAR_W, minWidth: SIDEBAR_MIN, flexShrink: 0, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.accent, paddingX: 1, children: [_jsx(Text, { bold: true, color: AIAIAI_COLORS.accent, children: "\uD83E\uDD16 $AIAIAI" }), aiaiPrice ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: changeColor(aiaiPrice.change), children: [aiaiPrice.priceUsd ? `$${parseFloat(aiaiPrice.priceUsd).toFixed(8)}` : "N/A", " ", aiaiPrice.change > 0 ? "▲" : aiaiPrice.change < 0 ? "▼" : "─", Math.abs(aiaiPrice.change).toFixed(1), "%"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["MCap: ", aiaiPrice.mcap ? `$${(aiaiPrice.mcap / 1000).toFixed(1)}k` : "N/A"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Liq: $", (aiaiPrice.liq / 1000).toFixed(1), "k"] })] })) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Loading\u2026" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\uD83D\uDCBC Wallets" }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Cold: ", coldBalance.sol.toFixed(2), " SOL"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" AIAIAI: ", coldBalance.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 0 })] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Action: ", actionBalance.sol.toFixed(2), " SOL"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" AIAIAI: ", actionBalance.aiaiai.toLocaleString(undefined, { maximumFractionDigits: 0 })] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Deposit: ", depositBalance.usdc.toFixed(2), " USDC"] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [" SOL: ", depositBalance.sol.toFixed(2)] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\u26A1 Actions" }), recentActions.length > 0 ? recentActions.map((a, i) => {
|
|
595
724
|
const col = a.type === "buy" ? AIAIAI_COLORS.success : a.type === "burn" ? AIAIAI_COLORS.error : AIAIAI_COLORS.muted;
|
|
596
725
|
const time = new Date(a.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
597
726
|
return _jsxs(Text, { color: col, children: [actionIcon(a.type), " ", time, " ", a.type, " ", a.amount.toLocaleString()] }, i);
|
|
598
|
-
}) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Waiting
|
|
727
|
+
}) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "Waiting\u2026" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\uD83D\uDCB5 Fees (0.5%)" }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Buy: $", fees.buyFees.toFixed(4)] }), _jsxs(Text, { color: AIAIAI_COLORS.muted, children: ["Burn: $", fees.burnFees.toFixed(4)] }), _jsxs(Text, { color: AIAIAI_COLORS.accent, bold: true, children: ["Total: $", fees.total.toFixed(4)] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\uD83D\uDC41\uFE0F Watch" }), watchList.length > 0 ? watchList.slice(0, 4).map((addr, i) => {
|
|
728
|
+
return _jsxs(Text, { color: AIAIAI_COLORS.muted, children: [addr.slice(0, 8), "\u2026", addr.slice(-6)] }, i);
|
|
729
|
+
}) : _jsx(Text, { color: AIAIAI_COLORS.muted, children: "No tokens watched" })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.dim, paddingX: 1, marginTop: 1, children: [_jsx(Text, { bold: true, children: "\uD83D\uDCF0 News" }), sidebarNews.length > 0 ? sidebarNews.slice(0, 4).map((n, i) => {
|
|
599
730
|
const sentColor = n.sentiment > 0.3 ? AIAIAI_COLORS.success : n.sentiment < -0.3 ? AIAIAI_COLORS.error : AIAIAI_COLORS.muted;
|
|
600
731
|
const title = n.title.length > 30 ? n.title.slice(0, 28) + "…" : n.title;
|
|
601
732
|
return _jsx(Text, { color: sentColor, children: title }, i);
|
package/dist/tui/REPL.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* REPL — scrolling message history +
|
|
2
|
+
* REPL — scrolling message history + feature-rich input box.
|
|
3
|
+
* Supports: multi-line (Shift+Enter), command history (↑/↓), tab completion.
|
|
3
4
|
*/
|
|
4
5
|
import React from "react";
|
|
5
6
|
export interface ChatMessage {
|