@darksol/terminal 0.9.1 → 0.10.0
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 +1 -1
- package/package.json +1 -1
- package/src/cli.js +221 -24
- package/src/llm/engine.js +8 -9
- package/src/llm/models.js +67 -0
- package/src/services/poker.js +937 -0
- package/src/setup/wizard.js +61 -3
- package/src/web/commands.js +351 -5
- package/src/web/server.js +6 -4
- package/src/web/terminal.js +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ A unified CLI for market intel, trading, AI-powered analysis, on-chain oracle, c
|
|
|
15
15
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
16
16
|
[](https://nodejs.org/)
|
|
17
17
|
|
|
18
|
-
- Current release: **0.9.
|
|
18
|
+
- Current release: **0.9.2**
|
|
19
19
|
- Changelog: `CHANGELOG.md`
|
|
20
20
|
|
|
21
21
|
## Install
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ import { executeLifiSwap, executeLifiBridge, checkBridgeStatus, showSupportedCha
|
|
|
17
17
|
import { topMovers, tokenDetail, compareTokens } from './services/market.js';
|
|
18
18
|
import { oracleFlip, oracleDice, oracleNumber, oracleShuffle, oracleHealth } from './services/oracle.js';
|
|
19
19
|
import { casinoBet, casinoTables, casinoStats, casinoReceipt, casinoHealth, casinoVerify } from './services/casino.js';
|
|
20
|
+
import { pokerNewGame, pokerAction, pokerStatus, pokerHistory } from './services/poker.js';
|
|
20
21
|
import { cardsCatalog, cardsOrder, cardsStatus } from './services/cards.js';
|
|
21
22
|
import { facilitatorHealth, facilitatorVerify, facilitatorSettle } from './services/facilitator.js';
|
|
22
23
|
import { buildersLeaderboard, buildersLookup, buildersFeed } from './services/builders.js';
|
|
@@ -32,6 +33,7 @@ import { clearMemories, exportMemories, getRecentMemories, searchMemories } from
|
|
|
32
33
|
import { getAgentStatus, planAgentGoal, runAgentTask } from './agent/index.js';
|
|
33
34
|
import { createRequire } from 'module';
|
|
34
35
|
import { resolve } from 'path';
|
|
36
|
+
import { getConfiguredModel, getProviderDefaultModel } from './llm/models.js';
|
|
35
37
|
const require = createRequire(import.meta.url);
|
|
36
38
|
const { version: PKG_VERSION } = require('../package.json');
|
|
37
39
|
|
|
@@ -40,7 +42,7 @@ export function cli(argv) {
|
|
|
40
42
|
|
|
41
43
|
program
|
|
42
44
|
.name('darksol')
|
|
43
|
-
.description(theme.gold('DARKSOL Terminal') + theme.dim('
|
|
45
|
+
.description(theme.gold('DARKSOL Terminal') + theme.dim(' - Ghost in the machine with teeth 🌑'))
|
|
44
46
|
.version(PKG_VERSION)
|
|
45
47
|
;
|
|
46
48
|
|
|
@@ -49,7 +51,7 @@ export function cli(argv) {
|
|
|
49
51
|
// ═══════════════════════════════════════
|
|
50
52
|
const wallet = program
|
|
51
53
|
.command('wallet')
|
|
52
|
-
.description('Wallet management
|
|
54
|
+
.description('Wallet management - create, import, list, balance');
|
|
53
55
|
|
|
54
56
|
wallet
|
|
55
57
|
.command('create [name]')
|
|
@@ -114,7 +116,7 @@ export function cli(argv) {
|
|
|
114
116
|
// ═══════════════════════════════════════
|
|
115
117
|
const trade = program
|
|
116
118
|
.command('trade')
|
|
117
|
-
.description('Trading
|
|
119
|
+
.description('Trading - swap, snipe, DCA');
|
|
118
120
|
|
|
119
121
|
trade
|
|
120
122
|
.command('swap')
|
|
@@ -162,14 +164,14 @@ export function cli(argv) {
|
|
|
162
164
|
// If LI.FI failed (not cancelled), fall back to direct
|
|
163
165
|
if (result?.error !== 'cancelled') {
|
|
164
166
|
const { warn: showWarn, info: showInfo } = await import('./ui/components.js');
|
|
165
|
-
showWarn('LI.FI route failed
|
|
167
|
+
showWarn('LI.FI route failed - falling back to direct Uniswap V3...');
|
|
166
168
|
console.log('');
|
|
167
169
|
} else {
|
|
168
170
|
return; // User cancelled, don't fallback
|
|
169
171
|
}
|
|
170
172
|
} catch {
|
|
171
173
|
const { warn: showWarn } = await import('./ui/components.js');
|
|
172
|
-
showWarn('LI.FI unavailable
|
|
174
|
+
showWarn('LI.FI unavailable - falling back to direct Uniswap V3...');
|
|
173
175
|
console.log('');
|
|
174
176
|
}
|
|
175
177
|
}
|
|
@@ -180,7 +182,7 @@ export function cli(argv) {
|
|
|
180
182
|
|
|
181
183
|
trade
|
|
182
184
|
.command('snipe <token>')
|
|
183
|
-
.description('Snipe a token
|
|
185
|
+
.description('Snipe a token - fast buy with ETH')
|
|
184
186
|
.requiredOption('-a, --amount <eth>', 'ETH amount to spend')
|
|
185
187
|
.option('-s, --slippage <percent>', 'Max slippage %', '1')
|
|
186
188
|
.option('-g, --gas <multiplier>', 'Gas priority multiplier', '1.5')
|
|
@@ -214,7 +216,7 @@ export function cli(argv) {
|
|
|
214
216
|
optimism: ['ETH/USDC', 'ETH/OP'],
|
|
215
217
|
polygon: ['POL/USDC', 'POL/WETH', 'USDC/USDT'],
|
|
216
218
|
};
|
|
217
|
-
showSection(`COMMON PAIRS
|
|
219
|
+
showSection(`COMMON PAIRS - ${chain.toUpperCase()}`);
|
|
218
220
|
const pairs = byChain[chain] || byChain.base;
|
|
219
221
|
pairs.forEach((p) => console.log(` ${theme.gold(p)}`));
|
|
220
222
|
console.log('');
|
|
@@ -227,7 +229,7 @@ export function cli(argv) {
|
|
|
227
229
|
// ═══════════════════════════════════════
|
|
228
230
|
const bridge = program
|
|
229
231
|
.command('bridge')
|
|
230
|
-
.description('Cross-chain bridge
|
|
232
|
+
.description('Cross-chain bridge - move tokens between chains via LI.FI');
|
|
231
233
|
|
|
232
234
|
bridge
|
|
233
235
|
.command('send')
|
|
@@ -319,7 +321,7 @@ export function cli(argv) {
|
|
|
319
321
|
// ═══════════════════════════════════════
|
|
320
322
|
const market = program
|
|
321
323
|
.command('market')
|
|
322
|
-
.description('Market intel
|
|
324
|
+
.description('Market intel - prices, movers, analysis');
|
|
323
325
|
|
|
324
326
|
market
|
|
325
327
|
.command('top')
|
|
@@ -330,7 +332,7 @@ export function cli(argv) {
|
|
|
330
332
|
|
|
331
333
|
market
|
|
332
334
|
.command('token <query>')
|
|
333
|
-
.description('Token detail
|
|
335
|
+
.description('Token detail - price, volume, liquidity')
|
|
334
336
|
.action((query) => tokenDetail(query));
|
|
335
337
|
|
|
336
338
|
market
|
|
@@ -375,7 +377,7 @@ export function cli(argv) {
|
|
|
375
377
|
// ═══════════════════════════════════════
|
|
376
378
|
const casino = program
|
|
377
379
|
.command('casino')
|
|
378
|
-
.description('The Clawsino
|
|
380
|
+
.description('The Clawsino - on-chain betting');
|
|
379
381
|
|
|
380
382
|
casino
|
|
381
383
|
.command('status')
|
|
@@ -415,12 +417,29 @@ export function cli(argv) {
|
|
|
415
417
|
.description('Verify bet on-chain')
|
|
416
418
|
.action((id) => casinoVerify(id));
|
|
417
419
|
|
|
420
|
+
const poker = program
|
|
421
|
+
.command('poker [subcommand]')
|
|
422
|
+
.description('GTO Poker Arena — heads-up holdem against the house');
|
|
423
|
+
|
|
424
|
+
poker
|
|
425
|
+
.option('--free', 'Free play mode (default)')
|
|
426
|
+
.option('--real', 'Real mode ($1 buy-in, $2 payout on win)')
|
|
427
|
+
.action(async (subcommand, opts) => {
|
|
428
|
+
if (subcommand === 'status') {
|
|
429
|
+
return showPokerCliStatus();
|
|
430
|
+
}
|
|
431
|
+
if (subcommand === 'history') {
|
|
432
|
+
return showPokerCliHistory();
|
|
433
|
+
}
|
|
434
|
+
return playPokerCli(opts);
|
|
435
|
+
});
|
|
436
|
+
|
|
418
437
|
// ═══════════════════════════════════════
|
|
419
438
|
// CARDS COMMANDS
|
|
420
439
|
// ═══════════════════════════════════════
|
|
421
440
|
const cards = program
|
|
422
441
|
.command('cards')
|
|
423
|
-
.description('Prepaid cards
|
|
442
|
+
.description('Prepaid cards - crypto to Visa/MC');
|
|
424
443
|
|
|
425
444
|
cards
|
|
426
445
|
.command('catalog')
|
|
@@ -497,7 +516,7 @@ export function cli(argv) {
|
|
|
497
516
|
// ═══════════════════════════════════════
|
|
498
517
|
const mail = program
|
|
499
518
|
.command('mail')
|
|
500
|
-
.description('📧 AgentMail
|
|
519
|
+
.description('📧 AgentMail - email for your agent');
|
|
501
520
|
|
|
502
521
|
mail
|
|
503
522
|
.command('setup')
|
|
@@ -751,7 +770,7 @@ export function cli(argv) {
|
|
|
751
770
|
// ═══════════════════════════════════════
|
|
752
771
|
program
|
|
753
772
|
.command('setup')
|
|
754
|
-
.description('First-run setup wizard
|
|
773
|
+
.description('First-run setup wizard - configure AI provider, chain, wallet')
|
|
755
774
|
.option('-f, --force', 'Re-run even if already configured')
|
|
756
775
|
.action((opts) => runSetupWizard({ force: opts.force }));
|
|
757
776
|
|
|
@@ -859,7 +878,7 @@ export function cli(argv) {
|
|
|
859
878
|
// ═══════════════════════════════════════
|
|
860
879
|
const keys = program
|
|
861
880
|
.command('keys')
|
|
862
|
-
.description('API key vault
|
|
881
|
+
.description('API key vault - store keys for LLMs, data providers, RPCs');
|
|
863
882
|
|
|
864
883
|
keys
|
|
865
884
|
.command('list')
|
|
@@ -882,7 +901,7 @@ export function cli(argv) {
|
|
|
882
901
|
// ═══════════════════════════════════════
|
|
883
902
|
const agent = program
|
|
884
903
|
.command('agent')
|
|
885
|
-
.description('Secure agent signer
|
|
904
|
+
.description('Secure agent signer - PK-isolated wallet for AI agents');
|
|
886
905
|
|
|
887
906
|
agent
|
|
888
907
|
.command('task <goal...>')
|
|
@@ -990,7 +1009,7 @@ export function cli(argv) {
|
|
|
990
1009
|
// ═══════════════════════════════════════
|
|
991
1010
|
const skills = program
|
|
992
1011
|
.command('skills')
|
|
993
|
-
.description('DARKSOL skills directory
|
|
1012
|
+
.description('DARKSOL skills directory - install agent skills');
|
|
994
1013
|
|
|
995
1014
|
skills
|
|
996
1015
|
.command('list')
|
|
@@ -1055,7 +1074,7 @@ export function cli(argv) {
|
|
|
1055
1074
|
.action(async (address, opts) => {
|
|
1056
1075
|
showMiniBanner();
|
|
1057
1076
|
if (address.length === 42 && address.startsWith('0x')) {
|
|
1058
|
-
// Could be token or wallet
|
|
1077
|
+
// Could be token or wallet - try token first
|
|
1059
1078
|
try {
|
|
1060
1079
|
await showTokenInfo(address, opts.chain);
|
|
1061
1080
|
} catch {
|
|
@@ -1072,7 +1091,7 @@ export function cli(argv) {
|
|
|
1072
1091
|
// ═══════════════════════════════════════
|
|
1073
1092
|
const script = program
|
|
1074
1093
|
.command('script')
|
|
1075
|
-
.description('Execution scripts
|
|
1094
|
+
.description('Execution scripts - automated trading strategies');
|
|
1076
1095
|
|
|
1077
1096
|
script
|
|
1078
1097
|
.command('create')
|
|
@@ -1137,6 +1156,8 @@ export function cli(argv) {
|
|
|
1137
1156
|
['Output', cfg.output],
|
|
1138
1157
|
['Slippage', `${cfg.slippage}%`],
|
|
1139
1158
|
['Gas Multiplier', `${cfg.gasMultiplier}x`],
|
|
1159
|
+
['LLM Provider', cfg.llm?.provider || theme.dim('(not set)')],
|
|
1160
|
+
['LLM Model', getConfiguredModel(cfg.llm?.provider || 'openai') || theme.dim('(default)')],
|
|
1140
1161
|
['Soul User', cfg.soul?.userName || theme.dim('(not set)')],
|
|
1141
1162
|
['Agent Name', cfg.soul?.agentName || 'Darksol'],
|
|
1142
1163
|
['Tone', cfg.soul?.tone || theme.dim('(not set)')],
|
|
@@ -1153,6 +1174,33 @@ export function cli(argv) {
|
|
|
1153
1174
|
console.log('');
|
|
1154
1175
|
});
|
|
1155
1176
|
|
|
1177
|
+
config
|
|
1178
|
+
.command('model [model]')
|
|
1179
|
+
.description('Set the LLM model')
|
|
1180
|
+
.option('-p, --provider <provider>', 'LLM provider (defaults to current provider)')
|
|
1181
|
+
.action((model, opts) => {
|
|
1182
|
+
const provider = opts.provider || getConfig('llm.provider') || 'openai';
|
|
1183
|
+
if (!model) {
|
|
1184
|
+
const current = getConfiguredModel(provider);
|
|
1185
|
+
const fallback = getProviderDefaultModel(provider);
|
|
1186
|
+
info(`Current model for ${provider}: ${current || '(not set)'}`);
|
|
1187
|
+
if (fallback) {
|
|
1188
|
+
info(`Provider default: ${fallback}`);
|
|
1189
|
+
}
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
if (opts.provider) {
|
|
1194
|
+
setConfig('llm.provider', provider);
|
|
1195
|
+
setConfig('llmProvider', provider);
|
|
1196
|
+
}
|
|
1197
|
+
setConfig('llm.model', model);
|
|
1198
|
+
if (provider === 'ollama') {
|
|
1199
|
+
setConfig('ollamaModel', model);
|
|
1200
|
+
}
|
|
1201
|
+
success(`LLM model for ${provider}: ${model}`);
|
|
1202
|
+
});
|
|
1203
|
+
|
|
1156
1204
|
config
|
|
1157
1205
|
.command('set <key> <value>')
|
|
1158
1206
|
.description('Set config value')
|
|
@@ -1170,7 +1218,7 @@ export function cli(argv) {
|
|
|
1170
1218
|
});
|
|
1171
1219
|
|
|
1172
1220
|
// ═══════════════════════════════════════
|
|
1173
|
-
// DASHBOARD (default)
|
|
1221
|
+
// DASHBOARD (default) - commands + optional AI
|
|
1174
1222
|
// ═══════════════════════════════════════
|
|
1175
1223
|
program
|
|
1176
1224
|
.command('dashboard', { isDefault: true })
|
|
@@ -1198,7 +1246,7 @@ export function cli(argv) {
|
|
|
1198
1246
|
|
|
1199
1247
|
// ── AI nudge or chat prompt ──
|
|
1200
1248
|
if (hasLLM) {
|
|
1201
|
-
console.log(theme.gold(' 💬 AI is ready
|
|
1249
|
+
console.log(theme.gold(' 💬 AI is ready - run ') + theme.label('darksol ai chat') + theme.gold(' or just ') + theme.label('darksol chat'));
|
|
1202
1250
|
console.log(theme.dim(' "swap 0.1 ETH for USDC" • "what\'s AERO at?" • any question'));
|
|
1203
1251
|
console.log('');
|
|
1204
1252
|
} else {
|
|
@@ -1222,7 +1270,7 @@ export function cli(argv) {
|
|
|
1222
1270
|
const { info, error: showError } = await import('./ui/components.js');
|
|
1223
1271
|
|
|
1224
1272
|
console.log('');
|
|
1225
|
-
info(`"${input}" isn't a command
|
|
1273
|
+
info(`"${input}" isn't a command - asking AI...`);
|
|
1226
1274
|
console.log('');
|
|
1227
1275
|
|
|
1228
1276
|
try {
|
|
@@ -1376,6 +1424,154 @@ async function chatResponse(llm, input) {
|
|
|
1376
1424
|
}
|
|
1377
1425
|
}
|
|
1378
1426
|
|
|
1427
|
+
function pokerModeFromOpts(opts = {}) {
|
|
1428
|
+
return opts.real ? 'real' : 'free';
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
function renderPokerCards(cards, hidden = false) {
|
|
1432
|
+
const suitMap = { s: '♠', h: '♥', d: '♦', c: '♣' };
|
|
1433
|
+
const colorize = (card, text) => {
|
|
1434
|
+
const suit = card[1];
|
|
1435
|
+
return suit === 'h' || suit === 'd' ? theme.error(text) : theme.bright(text);
|
|
1436
|
+
};
|
|
1437
|
+
|
|
1438
|
+
const source = hidden ? ['??', '??'] : cards;
|
|
1439
|
+
const rows = ['', '', '', '', ''];
|
|
1440
|
+
|
|
1441
|
+
for (const card of source) {
|
|
1442
|
+
if (card === '??') {
|
|
1443
|
+
rows[0] += `${theme.dim('┌─────┐')} `;
|
|
1444
|
+
rows[1] += `${theme.dim('│░░░░░│')} `;
|
|
1445
|
+
rows[2] += `${theme.dim('│░░▓░░│')} `;
|
|
1446
|
+
rows[3] += `${theme.dim('│░░░░░│')} `;
|
|
1447
|
+
rows[4] += `${theme.dim('└─────┘')} `;
|
|
1448
|
+
continue;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
const rank = card[0] === 'T' ? '10' : card[0];
|
|
1452
|
+
const suit = suitMap[card[1]];
|
|
1453
|
+
rows[0] += `${theme.dim('┌─────┐')} `;
|
|
1454
|
+
rows[1] += `${theme.dim('│')}${colorize(card, rank.padEnd(2, ' '))}${theme.dim(' │')} `;
|
|
1455
|
+
rows[2] += `${theme.dim('│ ')}${colorize(card, suit)}${theme.dim(' │')} `;
|
|
1456
|
+
rows[3] += `${theme.dim('│ ')}${colorize(card, rank.padStart(2, ' '))}${theme.dim('│')} `;
|
|
1457
|
+
rows[4] += `${theme.dim('└─────┘')} `;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
rows.forEach((row) => console.log(` ${row}`));
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
function showPokerState(status) {
|
|
1464
|
+
showSection(`POKER ARENA - ${status.mode === 'real' ? 'REAL MODE' : 'FREE MODE'}`);
|
|
1465
|
+
kvDisplay([
|
|
1466
|
+
['Street', status.street.toUpperCase()],
|
|
1467
|
+
['Dealer', status.dealer],
|
|
1468
|
+
['Pot', `${status.pot} chips`],
|
|
1469
|
+
['Current Bet', `${status.currentBet} chips`],
|
|
1470
|
+
['Your Stack', `${status.player.stack} chips`],
|
|
1471
|
+
['House Stack', `${status.house.stack} chips`],
|
|
1472
|
+
['To Act', status.currentActor || '-'],
|
|
1473
|
+
]);
|
|
1474
|
+
|
|
1475
|
+
console.log('');
|
|
1476
|
+
console.log(` ${theme.label('House')}`);
|
|
1477
|
+
renderPokerCards(status.house.hole, status.house.holeHidden);
|
|
1478
|
+
console.log('');
|
|
1479
|
+
console.log(` ${theme.label('Board')}`);
|
|
1480
|
+
if (status.community.length) renderPokerCards(status.community);
|
|
1481
|
+
else console.log(` ${theme.dim(' No community cards yet')}`);
|
|
1482
|
+
console.log('');
|
|
1483
|
+
console.log(` ${theme.label('You')}`);
|
|
1484
|
+
renderPokerCards(status.player.hole);
|
|
1485
|
+
console.log('');
|
|
1486
|
+
|
|
1487
|
+
if (status.street === 'finished') {
|
|
1488
|
+
const result = status.winner === 'player'
|
|
1489
|
+
? theme.success('WIN')
|
|
1490
|
+
: status.winner === 'house'
|
|
1491
|
+
? theme.error('LOSS')
|
|
1492
|
+
: theme.warning('PUSH');
|
|
1493
|
+
kvDisplay([
|
|
1494
|
+
['Result', result],
|
|
1495
|
+
['Summary', status.summary || '-'],
|
|
1496
|
+
['Your Hand', status.player.hand?.name || '-'],
|
|
1497
|
+
['House Hand', status.house.hand?.name || '-'],
|
|
1498
|
+
['Payout', status.mode === 'real' && status.winner === 'player' ? `$${status.payoutUsdc} USDC` : status.mode === 'real' ? '$0 USDC' : 'free mode'],
|
|
1499
|
+
]);
|
|
1500
|
+
console.log('');
|
|
1501
|
+
} else if (status.availableActions?.length) {
|
|
1502
|
+
info(`Actions: ${status.availableActions.join(', ')}`);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
async function playPokerCli(opts = {}) {
|
|
1507
|
+
const inquirer = (await import('inquirer')).default;
|
|
1508
|
+
const mode = pokerModeFromOpts(opts);
|
|
1509
|
+
const spin = spinner(`Opening ${mode === 'real' ? 'real-mode' : 'free-mode'} poker table...`).start();
|
|
1510
|
+
|
|
1511
|
+
try {
|
|
1512
|
+
let status = await pokerNewGame({ mode });
|
|
1513
|
+
spin.succeed('Table ready');
|
|
1514
|
+
|
|
1515
|
+
while (status && status.street !== 'finished') {
|
|
1516
|
+
console.log('');
|
|
1517
|
+
showPokerState(status);
|
|
1518
|
+
|
|
1519
|
+
if (status.currentActor !== 'player') {
|
|
1520
|
+
status = pokerStatus(status.id);
|
|
1521
|
+
continue;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
const { action } = await inquirer.prompt([{
|
|
1525
|
+
type: 'list',
|
|
1526
|
+
name: 'action',
|
|
1527
|
+
message: theme.gold('Pick your action:'),
|
|
1528
|
+
choices: status.availableActions.map((item) => ({
|
|
1529
|
+
name: item === 'all-in' ? 'all-in' : item,
|
|
1530
|
+
value: item,
|
|
1531
|
+
})),
|
|
1532
|
+
}]);
|
|
1533
|
+
|
|
1534
|
+
status = await pokerAction(status.id, action);
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
console.log('');
|
|
1538
|
+
showPokerState(status);
|
|
1539
|
+
} catch (err) {
|
|
1540
|
+
spin.fail('Poker table unavailable');
|
|
1541
|
+
error(err.message);
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
function showPokerCliStatus() {
|
|
1546
|
+
showMiniBanner();
|
|
1547
|
+
const status = pokerStatus();
|
|
1548
|
+
if (!status) {
|
|
1549
|
+
info('No active poker game');
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
showPokerState(status);
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
function showPokerCliHistory() {
|
|
1556
|
+
showMiniBanner();
|
|
1557
|
+
const items = pokerHistory();
|
|
1558
|
+
if (!items.length) {
|
|
1559
|
+
info('No poker hands played yet');
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
showSection('POKER HISTORY');
|
|
1564
|
+
items.slice(0, 10).forEach((item) => {
|
|
1565
|
+
const verdict = item.winner === 'player'
|
|
1566
|
+
? theme.success('W')
|
|
1567
|
+
: item.winner === 'house'
|
|
1568
|
+
? theme.error('L')
|
|
1569
|
+
: theme.warning('P');
|
|
1570
|
+
console.log(` ${verdict} ${theme.gold(item.mode.toUpperCase().padEnd(5))} ${theme.bright(item.summary)}`);
|
|
1571
|
+
});
|
|
1572
|
+
console.log('');
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1379
1575
|
function showCommandList() {
|
|
1380
1576
|
console.log('');
|
|
1381
1577
|
showSection('COMMANDS');
|
|
@@ -1399,10 +1595,11 @@ function showCommandList() {
|
|
|
1399
1595
|
['script', 'Execution scripts & strategies'],
|
|
1400
1596
|
['market', 'Market intel & token data'],
|
|
1401
1597
|
['oracle', 'On-chain random oracle'],
|
|
1402
|
-
['casino', 'The Clawsino
|
|
1598
|
+
['casino', 'The Clawsino - betting'],
|
|
1599
|
+
['poker', 'GTO Poker Arena — heads-up holdem'],
|
|
1403
1600
|
['cards', 'Prepaid Visa/MC cards'],
|
|
1404
1601
|
['builders', 'ERC-8021 builder index'],
|
|
1405
|
-
['mail', 'AgentMail
|
|
1602
|
+
['mail', 'AgentMail - email for your agent'],
|
|
1406
1603
|
['facilitator', 'x402 payment facilitator'],
|
|
1407
1604
|
['skills', 'Agent skill directory'],
|
|
1408
1605
|
['serve', 'Launch web terminal in browser'],
|
package/src/llm/engine.js
CHANGED
|
@@ -3,18 +3,19 @@ import { getKeyFromEnv, getKey } from '../config/keys.js';
|
|
|
3
3
|
import { getConfig } from '../config/store.js';
|
|
4
4
|
import { SessionMemory, extractMemories, searchMemories } from '../memory/index.js';
|
|
5
5
|
import { formatSystemPrompt as formatSoulSystemPrompt } from '../soul/index.js';
|
|
6
|
+
import { getProviderDefaultModel } from './models.js';
|
|
6
7
|
|
|
7
8
|
const PROVIDERS = {
|
|
8
9
|
openai: {
|
|
9
10
|
url: 'https://api.openai.com/v1/chat/completions',
|
|
10
|
-
defaultModel: '
|
|
11
|
+
defaultModel: getProviderDefaultModel('openai'),
|
|
11
12
|
authHeader: (key) => ({ Authorization: `Bearer ${key}` }),
|
|
12
13
|
parseResponse: (data) => data.choices?.[0]?.message?.content,
|
|
13
14
|
parseUsage: (data) => data.usage,
|
|
14
15
|
},
|
|
15
16
|
anthropic: {
|
|
16
17
|
url: 'https://api.anthropic.com/v1/messages',
|
|
17
|
-
defaultModel: '
|
|
18
|
+
defaultModel: getProviderDefaultModel('anthropic'),
|
|
18
19
|
authHeader: (key) => ({ 'x-api-key': key, 'anthropic-version': '2023-06-01' }),
|
|
19
20
|
buildBody: (model, messages, systemPrompt) => ({
|
|
20
21
|
model,
|
|
@@ -30,7 +31,7 @@ const PROVIDERS = {
|
|
|
30
31
|
},
|
|
31
32
|
openrouter: {
|
|
32
33
|
url: 'https://openrouter.ai/api/v1/chat/completions',
|
|
33
|
-
defaultModel: '
|
|
34
|
+
defaultModel: getProviderDefaultModel('openrouter'),
|
|
34
35
|
authHeader: (key) => ({
|
|
35
36
|
Authorization: `Bearer ${key}`,
|
|
36
37
|
'HTTP-Referer': 'https://darksol.net',
|
|
@@ -41,21 +42,21 @@ const PROVIDERS = {
|
|
|
41
42
|
},
|
|
42
43
|
minimax: {
|
|
43
44
|
url: 'https://api.minimax.io/v1/chat/completions',
|
|
44
|
-
defaultModel: '
|
|
45
|
+
defaultModel: getProviderDefaultModel('minimax'),
|
|
45
46
|
authHeader: (key) => ({ Authorization: `Bearer ${key}` }),
|
|
46
47
|
parseResponse: (data) => data.choices?.[0]?.message?.content,
|
|
47
48
|
parseUsage: (data) => data.usage,
|
|
48
49
|
},
|
|
49
50
|
ollama: {
|
|
50
51
|
url: null,
|
|
51
|
-
defaultModel: '
|
|
52
|
+
defaultModel: getProviderDefaultModel('ollama'),
|
|
52
53
|
authHeader: () => ({}),
|
|
53
54
|
parseResponse: (data) => data.choices?.[0]?.message?.content || data.message?.content,
|
|
54
55
|
parseUsage: () => ({ input: 0, output: 0 }),
|
|
55
56
|
},
|
|
56
57
|
bankr: {
|
|
57
58
|
url: 'https://llm.bankr.bot/v1/chat/completions',
|
|
58
|
-
defaultModel: '
|
|
59
|
+
defaultModel: getProviderDefaultModel('bankr'),
|
|
59
60
|
authHeader: (key) => ({ 'X-API-Key': key }),
|
|
60
61
|
parseResponse: (data) => data.choices?.[0]?.message?.content,
|
|
61
62
|
parseUsage: (data) => data.usage,
|
|
@@ -99,9 +100,7 @@ export class LLMEngine {
|
|
|
99
100
|
throw new Error(`Unknown LLM provider: ${this.provider}. Supported: ${Object.keys(PROVIDERS).join(', ')}`);
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
this.model = providerConfig.defaultModel;
|
|
104
|
-
}
|
|
103
|
+
this.model = this.model || providerConfig.defaultModel || getProviderDefaultModel(this.provider);
|
|
105
104
|
|
|
106
105
|
if (this.provider === 'ollama') {
|
|
107
106
|
const host = this.apiKey || getConfig('llm.ollamaHost') || 'http://localhost:11434';
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { getConfig } from '../config/store.js';
|
|
2
|
+
|
|
3
|
+
export const MODEL_CATALOG = {
|
|
4
|
+
openai: {
|
|
5
|
+
defaultModel: 'gpt-5.4',
|
|
6
|
+
choices: [
|
|
7
|
+
{ value: 'gpt-5.4', label: 'gpt-5.4', desc: 'flagship, complex reasoning' },
|
|
8
|
+
{ value: 'gpt-5-mini', label: 'gpt-5-mini', desc: 'fast, lower cost' },
|
|
9
|
+
{ value: 'gpt-4o', label: 'gpt-4o', desc: 'previous gen, still good' },
|
|
10
|
+
{ value: 'o3', label: 'o3', desc: 'reasoning model' },
|
|
11
|
+
],
|
|
12
|
+
},
|
|
13
|
+
anthropic: {
|
|
14
|
+
defaultModel: 'claude-sonnet-4-6',
|
|
15
|
+
choices: [
|
|
16
|
+
{ value: 'claude-opus-4-6', label: 'claude-opus-4-6', desc: 'most intelligent, agents+coding' },
|
|
17
|
+
{ value: 'claude-sonnet-4-6', label: 'claude-sonnet-4-6', desc: 'best speed/intelligence balance' },
|
|
18
|
+
{ value: 'claude-haiku-4-5', label: 'claude-haiku-4-5', desc: 'fastest, near-frontier' },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
openrouter: {
|
|
22
|
+
defaultModel: 'anthropic/claude-sonnet-4-6',
|
|
23
|
+
choices: [
|
|
24
|
+
{ value: 'anthropic/claude-sonnet-4-6', label: 'anthropic/claude-sonnet-4-6', desc: 'popular pick' },
|
|
25
|
+
{ value: 'openai/gpt-5.4', label: 'openai/gpt-5.4', desc: 'popular pick' },
|
|
26
|
+
{ value: 'google/gemini-2.5-pro', label: 'google/gemini-2.5-pro', desc: 'popular pick' },
|
|
27
|
+
{ value: 'meta-llama/llama-4-maverick', label: 'meta-llama/llama-4-maverick', desc: 'popular pick' },
|
|
28
|
+
{ value: 'deepseek/deepseek-r1', label: 'deepseek/deepseek-r1', desc: 'popular pick' },
|
|
29
|
+
],
|
|
30
|
+
allowCustom: true,
|
|
31
|
+
},
|
|
32
|
+
minimax: {
|
|
33
|
+
defaultModel: 'MiniMax-M2.5',
|
|
34
|
+
choices: [
|
|
35
|
+
{ value: 'MiniMax-M2.5', label: 'MiniMax-M2.5', desc: 'flagship, 204K context, ~60 tps' },
|
|
36
|
+
{ value: 'MiniMax-M2.5-highspeed', label: 'MiniMax-M2.5-highspeed', desc: 'same perf, ~100 tps' },
|
|
37
|
+
{ value: 'MiniMax-M2.1', label: 'MiniMax-M2.1', desc: 'code-focused' },
|
|
38
|
+
{ value: 'MiniMax-M2.1-highspeed', label: 'MiniMax-M2.1-highspeed', desc: 'code-focused, faster' },
|
|
39
|
+
{ value: 'MiniMax-M2', label: 'MiniMax-M2', desc: 'agentic, advanced reasoning' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
ollama: {
|
|
43
|
+
defaultModel: 'llama3.1',
|
|
44
|
+
textInput: true,
|
|
45
|
+
},
|
|
46
|
+
bankr: {
|
|
47
|
+
defaultModel: 'claude-sonnet-4.6',
|
|
48
|
+
managed: true,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export function getProviderDefaultModel(provider) {
|
|
53
|
+
return MODEL_CATALOG[provider]?.defaultModel || null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function getConfiguredProvider(fallback = 'openai') {
|
|
57
|
+
return getConfig('llm.provider') || fallback;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function getConfiguredModel(provider = getConfiguredProvider()) {
|
|
61
|
+
const configured = getConfig('llm.model');
|
|
62
|
+
return configured || getProviderDefaultModel(provider);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function getModelSelectionMeta(provider = getConfiguredProvider()) {
|
|
66
|
+
return MODEL_CATALOG[provider] || { defaultModel: null };
|
|
67
|
+
}
|