@moly-mcp/lido 1.0.2 → 1.0.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/bin.js
CHANGED
|
@@ -206,7 +206,7 @@ async function main() {
|
|
|
206
206
|
case "setup": {
|
|
207
207
|
const { cfg, terminalMode } = await runWizard();
|
|
208
208
|
if (terminalMode) {
|
|
209
|
-
const { startChatSession } = await import("./session-
|
|
209
|
+
const { startChatSession } = await import("./session-ZXWCIUKX.js");
|
|
210
210
|
await startChatSession(cfg);
|
|
211
211
|
} else {
|
|
212
212
|
await startServer();
|
|
@@ -251,7 +251,7 @@ async function main() {
|
|
|
251
251
|
if (!configExists()) {
|
|
252
252
|
const { cfg, terminalMode } = await runWizard();
|
|
253
253
|
if (terminalMode) {
|
|
254
|
-
const { startChatSession } = await import("./session-
|
|
254
|
+
const { startChatSession } = await import("./session-ZXWCIUKX.js");
|
|
255
255
|
await startChatSession(cfg);
|
|
256
256
|
} else {
|
|
257
257
|
await startServer();
|
|
@@ -20,6 +20,8 @@ import "./chunk-PIFEXJ56.js";
|
|
|
20
20
|
|
|
21
21
|
// src/chat/session.ts
|
|
22
22
|
import * as readline from "readline";
|
|
23
|
+
import * as fs from "fs";
|
|
24
|
+
import * as path from "path";
|
|
23
25
|
|
|
24
26
|
// src/chat/providers.ts
|
|
25
27
|
async function callAnthropic(apiKey, model, messages, tools) {
|
|
@@ -394,50 +396,86 @@ async function executeTool(name, args) {
|
|
|
394
396
|
}
|
|
395
397
|
|
|
396
398
|
// src/chat/session.ts
|
|
397
|
-
var
|
|
398
|
-
var
|
|
399
|
-
var
|
|
400
|
-
var
|
|
401
|
-
var
|
|
402
|
-
var
|
|
403
|
-
var
|
|
404
|
-
var
|
|
405
|
-
|
|
399
|
+
var R = "\x1B[0m";
|
|
400
|
+
var B = "\x1B[1m";
|
|
401
|
+
var D = "\x1B[2m";
|
|
402
|
+
var CY = "\x1B[36m";
|
|
403
|
+
var GR = "\x1B[32m";
|
|
404
|
+
var YE = "\x1B[33m";
|
|
405
|
+
var BL = "\x1B[34m";
|
|
406
|
+
var RE = "\x1B[31m";
|
|
407
|
+
var MA = "\x1B[35m";
|
|
408
|
+
var LOGO = `
|
|
409
|
+
${CY}${B} \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557${R}
|
|
410
|
+
${CY}${B} \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D${R}
|
|
411
|
+
${CY}${B} \u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2554\u255D ${R}
|
|
412
|
+
${CY}${B} \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2554\u255D ${R}
|
|
413
|
+
${CY}${B} \u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 ${R}
|
|
414
|
+
${CY}${B} \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D ${R}
|
|
415
|
+
${D} powered by Lido \u2B21${R}
|
|
416
|
+
`;
|
|
417
|
+
function ln(text = "") {
|
|
406
418
|
process.stdout.write(text + "\n");
|
|
407
419
|
}
|
|
420
|
+
function saveTrade(toolName, args, result) {
|
|
421
|
+
try {
|
|
422
|
+
const tradesDir = path.join(process.cwd(), "trades");
|
|
423
|
+
if (!fs.existsSync(tradesDir)) fs.mkdirSync(tradesDir, { recursive: true });
|
|
424
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
425
|
+
const file = path.join(tradesDir, `${today}.jsonl`);
|
|
426
|
+
const record = JSON.stringify({
|
|
427
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
428
|
+
tool: toolName,
|
|
429
|
+
args,
|
|
430
|
+
result: (() => {
|
|
431
|
+
try {
|
|
432
|
+
return JSON.parse(result);
|
|
433
|
+
} catch {
|
|
434
|
+
return result;
|
|
435
|
+
}
|
|
436
|
+
})()
|
|
437
|
+
});
|
|
438
|
+
fs.appendFileSync(file, record + "\n");
|
|
439
|
+
} catch {
|
|
440
|
+
}
|
|
441
|
+
}
|
|
408
442
|
function printBanner(cfg) {
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
print("");
|
|
443
|
+
const modeLabel = cfg.mode === "simulation" ? `${YE}\u25CF SIMULATION${R}` : `${RE}\u25CF LIVE${R}`;
|
|
444
|
+
ln(LOGO);
|
|
445
|
+
ln(` ${modeLabel} ${D}${cfg.network} \xB7 ${cfg.ai?.model ?? ""}${R}`);
|
|
446
|
+
ln(` ${D}type "exit" to quit${R}`);
|
|
447
|
+
ln(` ${D}${"\u2500".repeat(48)}${R}`);
|
|
448
|
+
ln();
|
|
416
449
|
}
|
|
450
|
+
var WRITE_TOOLS = /* @__PURE__ */ new Set([
|
|
451
|
+
"stake_eth",
|
|
452
|
+
"request_withdrawal",
|
|
453
|
+
"claim_withdrawals",
|
|
454
|
+
"wrap_steth",
|
|
455
|
+
"unwrap_wsteth",
|
|
456
|
+
"cast_vote"
|
|
457
|
+
]);
|
|
417
458
|
async function startChatSession(cfg) {
|
|
418
459
|
if (!cfg.ai) {
|
|
419
|
-
|
|
460
|
+
ln(`${RE}No AI provider configured. Run: moly setup${R}`);
|
|
420
461
|
process.exit(1);
|
|
421
462
|
}
|
|
422
463
|
const { provider, apiKey, model } = cfg.ai;
|
|
423
464
|
const messages = [
|
|
424
465
|
{
|
|
425
466
|
role: "user",
|
|
426
|
-
content: `You are Moly, an AI assistant for
|
|
467
|
+
content: `You are Moly, an AI assistant for Lido Finance on ${cfg.network}. Mode: ${cfg.mode} (${cfg.mode === "simulation" ? "dry-run, nothing broadcast" : "LIVE \u2014 real on-chain transactions"}). Help stake ETH, manage withdrawals, wrap/unwrap tokens, governance. Be concise. For live transactions always confirm with the user first.`
|
|
427
468
|
},
|
|
428
469
|
{
|
|
429
470
|
role: "assistant",
|
|
430
|
-
content: `
|
|
471
|
+
content: `Ready. I'm Moly on ${cfg.network} in ${cfg.mode} mode. What would you like to do?`
|
|
431
472
|
}
|
|
432
473
|
];
|
|
433
474
|
printBanner(cfg);
|
|
434
|
-
const rl = readline.createInterface({
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
});
|
|
439
|
-
const prompt = () => new Promise((resolve) => {
|
|
440
|
-
rl.question(`${BOLD}${BLUE}you${RESET} \u203A `, resolve);
|
|
475
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
476
|
+
const prompt = () => new Promise((resolve, reject) => {
|
|
477
|
+
rl.question(`${B}${BL}you${R} \u203A `, resolve);
|
|
478
|
+
rl.once("close", () => reject(new Error("closed")));
|
|
441
479
|
});
|
|
442
480
|
while (true) {
|
|
443
481
|
let input;
|
|
@@ -447,43 +485,45 @@ async function startChatSession(cfg) {
|
|
|
447
485
|
break;
|
|
448
486
|
}
|
|
449
487
|
if (!input) continue;
|
|
450
|
-
if (input
|
|
451
|
-
|
|
488
|
+
if (input === "exit" || input === "quit") {
|
|
489
|
+
ln(`${D}Goodbye.${R}`);
|
|
452
490
|
rl.close();
|
|
453
491
|
process.exit(0);
|
|
454
492
|
}
|
|
455
493
|
messages.push({ role: "user", content: input });
|
|
456
494
|
try {
|
|
457
495
|
while (true) {
|
|
458
|
-
|
|
496
|
+
ln(`${D} \u2699 thinking...${R}`);
|
|
459
497
|
const response = await callAi(provider, apiKey, model, messages, TOOL_DEFS);
|
|
460
|
-
process.stdout.write(" ".repeat(20) + "\r");
|
|
461
498
|
messages.push(response.rawAssistantMessage);
|
|
462
499
|
if (response.toolCalls.length > 0) {
|
|
463
500
|
const toolResults = [];
|
|
464
501
|
for (const tc of response.toolCalls) {
|
|
465
|
-
|
|
502
|
+
ln(`${D} \u21B3 ${MA}${tc.name}${R}${D} ${JSON.stringify(tc.args)}${R}`);
|
|
466
503
|
const result = await executeTool(tc.name, tc.args);
|
|
467
|
-
|
|
504
|
+
ln(`${D} ${result.slice(0, 300)}${result.length > 300 ? "\u2026" : ""}${R}`);
|
|
505
|
+
if (WRITE_TOOLS.has(tc.name)) {
|
|
506
|
+
saveTrade(tc.name, tc.args, result);
|
|
507
|
+
}
|
|
468
508
|
toolResults.push(makeToolResultMessage(provider, tc.id, tc.name, result));
|
|
469
509
|
}
|
|
470
510
|
messages.push(...toolResults);
|
|
471
511
|
if (response.text) {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
512
|
+
ln();
|
|
513
|
+
ln(`${B}${GR}moly${R} \u203A ${response.text}`);
|
|
514
|
+
ln();
|
|
475
515
|
}
|
|
476
516
|
continue;
|
|
477
517
|
}
|
|
478
518
|
if (response.text) {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
519
|
+
ln();
|
|
520
|
+
ln(`${B}${GR}moly${R} \u203A ${response.text}`);
|
|
521
|
+
ln();
|
|
482
522
|
}
|
|
483
523
|
break;
|
|
484
524
|
}
|
|
485
525
|
} catch (err) {
|
|
486
|
-
|
|
526
|
+
ln(`${RE}Error: ${err.message}${R}`);
|
|
487
527
|
messages.pop();
|
|
488
528
|
}
|
|
489
529
|
}
|
package/package.json
CHANGED