nyxora 1.0.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/.env.example +17 -0
- package/IDENTITY.md +8 -0
- package/README.md +61 -0
- package/SECURITY.md +19 -0
- package/config.yaml +10 -0
- package/dashboard/README.md +73 -0
- package/dashboard/eslint.config.js +22 -0
- package/dashboard/index.html +13 -0
- package/dashboard/package-lock.json +2737 -0
- package/dashboard/package.json +31 -0
- package/dashboard/public/favicon.svg +1 -0
- package/dashboard/public/icons.svg +24 -0
- package/dashboard/src/App.css +184 -0
- package/dashboard/src/App.tsx +485 -0
- package/dashboard/src/BalanceWidget.tsx +65 -0
- package/dashboard/src/MarketWidget.tsx +73 -0
- package/dashboard/src/Memory.tsx +109 -0
- package/dashboard/src/Overview.tsx +156 -0
- package/dashboard/src/Settings.tsx +213 -0
- package/dashboard/src/Skills.tsx +97 -0
- package/dashboard/src/SwapWidget.tsx +130 -0
- package/dashboard/src/TransactionWidget.tsx +86 -0
- package/dashboard/src/assets/hero.png +0 -0
- package/dashboard/src/assets/react.svg +1 -0
- package/dashboard/src/assets/vite.svg +1 -0
- package/dashboard/src/index.css +508 -0
- package/dashboard/src/main.tsx +10 -0
- package/dashboard/src/overview.css +304 -0
- package/dashboard/tsconfig.app.json +25 -0
- package/dashboard/tsconfig.json +7 -0
- package/dashboard/tsconfig.node.json +24 -0
- package/dashboard/vite.config.ts +7 -0
- package/dist/agent/reasoning.js +254 -0
- package/dist/config/parser.js +36 -0
- package/dist/config/paths.js +35 -0
- package/dist/gateway/cli.js +86 -0
- package/dist/gateway/server.js +154 -0
- package/dist/gateway/telegram.js +45 -0
- package/dist/gateway/test.js +50 -0
- package/dist/gateway/tracker.js +49 -0
- package/dist/memory/logger.js +50 -0
- package/dist/src/agent/reasoning.js +96 -0
- package/dist/src/config/parser.js +25 -0
- package/dist/src/gateway/cli.js +79 -0
- package/dist/src/memory/logger.js +50 -0
- package/dist/src/web3/config.js +80 -0
- package/dist/src/web3/skills/getBalance.js +43 -0
- package/dist/web3/config.js +83 -0
- package/dist/web3/skills/getBalance.js +80 -0
- package/dist/web3/skills/getPrice.js +44 -0
- package/dist/web3/skills/swapToken.js +71 -0
- package/dist/web3/skills/transfer.js +48 -0
- package/package.json +38 -0
- package/src/agent/reasoning.d.ts +2 -0
- package/src/agent/reasoning.d.ts.map +1 -0
- package/src/agent/reasoning.js +97 -0
- package/src/agent/reasoning.js.map +1 -0
- package/src/agent/reasoning.ts +232 -0
- package/src/config/parser.d.ts +17 -0
- package/src/config/parser.d.ts.map +1 -0
- package/src/config/parser.js +26 -0
- package/src/config/parser.js.map +1 -0
- package/src/config/parser.ts +47 -0
- package/src/config/paths.ts +33 -0
- package/src/gateway/cli.d.ts +3 -0
- package/src/gateway/cli.d.ts.map +1 -0
- package/src/gateway/cli.js +80 -0
- package/src/gateway/cli.js.map +1 -0
- package/src/gateway/cli.ts +58 -0
- package/src/gateway/server.ts +131 -0
- package/src/gateway/telegram.ts +47 -0
- package/src/gateway/test.ts +16 -0
- package/src/gateway/tracker.ts +70 -0
- package/src/memory/logger.d.ts +18 -0
- package/src/memory/logger.d.ts.map +1 -0
- package/src/memory/logger.js +51 -0
- package/src/memory/logger.js.map +1 -0
- package/src/memory/logger.ts +57 -0
- package/src/web3/config.d.ts +793 -0
- package/src/web3/config.d.ts.map +1 -0
- package/src/web3/config.js +81 -0
- package/src/web3/config.js.map +1 -0
- package/src/web3/config.ts +51 -0
- package/src/web3/skills/getBalance.d.ts +25 -0
- package/src/web3/skills/getBalance.d.ts.map +1 -0
- package/src/web3/skills/getBalance.js +46 -0
- package/src/web3/skills/getBalance.js.map +1 -0
- package/src/web3/skills/getBalance.ts +48 -0
- package/src/web3/skills/getPrice.ts +43 -0
- package/src/web3/skills/swapToken.ts +69 -0
- package/src/web3/skills/transfer.ts +47 -0
- package/tsconfig.json +13 -0
- package/user.md +10 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const fs_1 = __importDefault(require("fs"));
|
|
41
|
+
const path_1 = __importDefault(require("path"));
|
|
42
|
+
const dotenv = __importStar(require("dotenv"));
|
|
43
|
+
const open_1 = __importDefault(require("open"));
|
|
44
|
+
const paths_1 = require("../config/paths");
|
|
45
|
+
const server_1 = require("./server");
|
|
46
|
+
// 1. Determine configuration directory
|
|
47
|
+
const appDir = (0, paths_1.getAppDir)();
|
|
48
|
+
const isGlobalMode = appDir !== process.cwd();
|
|
49
|
+
console.log(`================================`);
|
|
50
|
+
console.log(`š¤ Nyxora CLI Agent Booting Up...`);
|
|
51
|
+
console.log(`š Config Directory: ${appDir}`);
|
|
52
|
+
console.log(`================================`);
|
|
53
|
+
// 2. Setup boilerplate files if in global mode and they don't exist
|
|
54
|
+
if (isGlobalMode) {
|
|
55
|
+
const globalEnvPath = path_1.default.join(appDir, '.env');
|
|
56
|
+
const globalUserMdPath = path_1.default.join(appDir, 'user.md');
|
|
57
|
+
const globalIdentityMdPath = path_1.default.join(appDir, 'IDENTITY.md');
|
|
58
|
+
// Copy .env.example to ~/.nyxora/.env if it doesn't exist
|
|
59
|
+
if (!fs_1.default.existsSync(globalEnvPath)) {
|
|
60
|
+
const exampleEnvPath = path_1.default.resolve(__dirname, '../../../.env.example');
|
|
61
|
+
if (fs_1.default.existsSync(exampleEnvPath)) {
|
|
62
|
+
fs_1.default.copyFileSync(exampleEnvPath, globalEnvPath);
|
|
63
|
+
console.log(`[Setup] Created default .env at ${globalEnvPath}`);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
fs_1.default.writeFileSync(globalEnvPath, '# Nyxora Environment Variables\nOPENAI_API_KEY=\nGEMINI_API_KEY=\nTELEGRAM_BOT_TOKEN=\n');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!fs_1.default.existsSync(globalUserMdPath)) {
|
|
70
|
+
fs_1.default.writeFileSync(globalUserMdPath, 'Tuliskan instruksi kustom, aturan khusus, profil pengguna, atau persona yang Anda inginkan untuk Nyxora AI di file ini.\n');
|
|
71
|
+
}
|
|
72
|
+
if (!fs_1.default.existsSync(globalIdentityMdPath)) {
|
|
73
|
+
fs_1.default.writeFileSync(globalIdentityMdPath, 'Kamu adalah Nyxora, asisten Web3 pintar.\n');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// 3. Load Environment Variables from the determined directory
|
|
77
|
+
dotenv.config({ path: path_1.default.join(appDir, '.env') });
|
|
78
|
+
// 4. Start the Express API Server (which also serves the static dashboard and Telegram bot)
|
|
79
|
+
(0, server_1.startServer)();
|
|
80
|
+
// 5. Open the Dashboard in the default browser
|
|
81
|
+
const PORT = process.env.PORT || 3000;
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
const url = `http://localhost:${PORT}`;
|
|
84
|
+
console.log(`š Opening Dashboard at ${url}`);
|
|
85
|
+
(0, open_1.default)(url);
|
|
86
|
+
}, 1500);
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.startServer = startServer;
|
|
40
|
+
const express_1 = __importDefault(require("express"));
|
|
41
|
+
const cors_1 = __importDefault(require("cors"));
|
|
42
|
+
const path_1 = __importDefault(require("path"));
|
|
43
|
+
const dotenv = __importStar(require("dotenv"));
|
|
44
|
+
const paths_1 = require("../config/paths");
|
|
45
|
+
dotenv.config({ path: (0, paths_1.getPath)('.env') });
|
|
46
|
+
const reasoning_1 = require("../agent/reasoning");
|
|
47
|
+
const parser_1 = require("../config/parser");
|
|
48
|
+
const tracker_1 = require("./tracker");
|
|
49
|
+
const getBalance_1 = require("../web3/skills/getBalance");
|
|
50
|
+
const transfer_1 = require("../web3/skills/transfer");
|
|
51
|
+
const getPrice_1 = require("../web3/skills/getPrice");
|
|
52
|
+
const swapToken_1 = require("../web3/skills/swapToken");
|
|
53
|
+
const telegram_1 = require("./telegram");
|
|
54
|
+
// Intercept console.log and console.error
|
|
55
|
+
const originalLog = console.log;
|
|
56
|
+
const originalError = console.error;
|
|
57
|
+
console.log = function (...args) {
|
|
58
|
+
tracker_1.Tracker.addGatewayLog(args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '));
|
|
59
|
+
originalLog.apply(console, args);
|
|
60
|
+
};
|
|
61
|
+
console.error = function (...args) {
|
|
62
|
+
tracker_1.Tracker.addGatewayLog(args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '), { level: 'error' });
|
|
63
|
+
originalError.apply(console, args);
|
|
64
|
+
};
|
|
65
|
+
const app = (0, express_1.default)();
|
|
66
|
+
app.use((0, cors_1.default)());
|
|
67
|
+
app.use(express_1.default.json());
|
|
68
|
+
// Serve static frontend from dashboard/dist
|
|
69
|
+
app.use(express_1.default.static(path_1.default.join(__dirname, '../../../dashboard/dist')));
|
|
70
|
+
app.get('/api/history', (req, res) => {
|
|
71
|
+
try {
|
|
72
|
+
const history = reasoning_1.logger.getHistory();
|
|
73
|
+
// Filter out internal system prompt for the frontend
|
|
74
|
+
const cleanHistory = history.filter((msg) => msg.role !== 'system');
|
|
75
|
+
res.json(cleanHistory);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
res.status(500).json({ error: error.message });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
app.delete('/api/history', (req, res) => {
|
|
82
|
+
try {
|
|
83
|
+
reasoning_1.logger.clear();
|
|
84
|
+
tracker_1.Tracker.addEvent('memory.cleared');
|
|
85
|
+
res.json({ success: true });
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
res.status(500).json({ error: error.message });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
app.get('/api/config', (req, res) => {
|
|
92
|
+
try {
|
|
93
|
+
const config = (0, parser_1.loadConfig)();
|
|
94
|
+
res.json(config);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
res.status(500).json({ error: error.message });
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
app.post('/api/config', (req, res) => {
|
|
101
|
+
try {
|
|
102
|
+
// Save new configuration to file
|
|
103
|
+
(0, parser_1.saveConfig)(req.body);
|
|
104
|
+
tracker_1.Tracker.addEvent('config.updated', { provider: req.body.llm?.provider });
|
|
105
|
+
res.json({ success: true });
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
res.status(500).json({ error: error.message });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
app.get('/api/stats', (req, res) => {
|
|
112
|
+
res.json(tracker_1.Tracker.getStats());
|
|
113
|
+
});
|
|
114
|
+
app.get('/api/logs', (req, res) => {
|
|
115
|
+
res.json(tracker_1.Tracker.getLogs());
|
|
116
|
+
});
|
|
117
|
+
app.get('/api/skills', (req, res) => {
|
|
118
|
+
res.json([
|
|
119
|
+
getBalance_1.getBalanceToolDefinition,
|
|
120
|
+
transfer_1.transferToolDefinition,
|
|
121
|
+
getPrice_1.getPriceToolDefinition,
|
|
122
|
+
swapToken_1.swapTokenToolDefinition
|
|
123
|
+
]);
|
|
124
|
+
});
|
|
125
|
+
app.post('/api/chat', async (req, res) => {
|
|
126
|
+
try {
|
|
127
|
+
const { message } = req.body;
|
|
128
|
+
if (!message) {
|
|
129
|
+
return res.status(400).json({ error: 'Message is required' });
|
|
130
|
+
}
|
|
131
|
+
// Process input (this will automatically add to memory)
|
|
132
|
+
const response = await (0, reasoning_1.processUserInput)(message);
|
|
133
|
+
res.json({ response });
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
res.status(500).json({ error: error.message });
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
// Fallback for React Router (Single Page Application)
|
|
140
|
+
app.get('*', (req, res) => {
|
|
141
|
+
res.sendFile(path_1.default.join(__dirname, '../../../dashboard/dist/index.html'));
|
|
142
|
+
});
|
|
143
|
+
function startServer() {
|
|
144
|
+
const PORT = process.env.PORT || 3000;
|
|
145
|
+
app.listen(PORT, () => {
|
|
146
|
+
console.log(`š¤ Nyxora API Server running on port ${PORT}`);
|
|
147
|
+
// Start the Telegram bot listener
|
|
148
|
+
(0, telegram_1.startTelegramBot)();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
// Start server if this file is run directly
|
|
152
|
+
if (require.main === module) {
|
|
153
|
+
startServer();
|
|
154
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startTelegramBot = startTelegramBot;
|
|
7
|
+
const node_telegram_bot_api_1 = __importDefault(require("node-telegram-bot-api"));
|
|
8
|
+
const reasoning_1 = require("../agent/reasoning");
|
|
9
|
+
function startTelegramBot() {
|
|
10
|
+
const token = process.env.TELEGRAM_BOT_TOKEN;
|
|
11
|
+
if (!token) {
|
|
12
|
+
console.log('[Telegram] No TELEGRAM_BOT_TOKEN found in .env. Bot is disabled.');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const bot = new node_telegram_bot_api_1.default(token, { polling: true });
|
|
17
|
+
bot.on('message', async (msg) => {
|
|
18
|
+
const chatId = msg.chat.id;
|
|
19
|
+
const text = msg.text;
|
|
20
|
+
if (!text)
|
|
21
|
+
return;
|
|
22
|
+
// Log incoming message
|
|
23
|
+
console.log(`[Telegram] Received from ${msg.from?.first_name}: ${text}`);
|
|
24
|
+
// Send typing action to Telegram
|
|
25
|
+
bot.sendChatAction(chatId, 'typing');
|
|
26
|
+
try {
|
|
27
|
+
// Feed the message to the AI agent
|
|
28
|
+
const response = await (0, reasoning_1.processUserInput)(text);
|
|
29
|
+
// Send the AI's response back to Telegram
|
|
30
|
+
bot.sendMessage(chatId, response);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.error('[Telegram] Error processing message:', error);
|
|
34
|
+
bot.sendMessage(chatId, 'ā Maaf, saya mengalami gangguan saat memproses pesan Anda.');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
bot.on('polling_error', (error) => {
|
|
38
|
+
console.error('[Telegram] Polling error:', error);
|
|
39
|
+
});
|
|
40
|
+
console.log('š¤ Telegram Bot is running and listening for messages...');
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.error('[Telegram] Failed to initialize bot:', error);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const reasoning_1 = require("../agent/reasoning");
|
|
37
|
+
const dotenv = __importStar(require("dotenv"));
|
|
38
|
+
dotenv.config();
|
|
39
|
+
async function run() {
|
|
40
|
+
console.log('š¤ Agent Test Started...');
|
|
41
|
+
console.log('š¤ You: Tolong cek saldo native di jaringan ethereum');
|
|
42
|
+
try {
|
|
43
|
+
const response = await (0, reasoning_1.processUserInput)('Tolong cek saldo native di jaringan ethereum');
|
|
44
|
+
console.log(`\nš¤ Nyxora Agent: ${response}\n`);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.error(`Error: ${err.message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
run();
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Tracker = void 0;
|
|
4
|
+
const stats = {
|
|
5
|
+
cost: 0,
|
|
6
|
+
tokens: 0,
|
|
7
|
+
messages: 0
|
|
8
|
+
};
|
|
9
|
+
const eventLogs = [];
|
|
10
|
+
const gatewayLogs = [];
|
|
11
|
+
const MAX_LOGS = 100;
|
|
12
|
+
function formatTime() {
|
|
13
|
+
const now = new Date();
|
|
14
|
+
return now.toTimeString().split(' ')[0]; // Returns HH:MM:SS
|
|
15
|
+
}
|
|
16
|
+
exports.Tracker = {
|
|
17
|
+
addTokens: (amount, provider) => {
|
|
18
|
+
stats.tokens += amount;
|
|
19
|
+
// Simple mock cost calculation
|
|
20
|
+
let rate = 0;
|
|
21
|
+
if (provider === 'openai')
|
|
22
|
+
rate = 0.00002;
|
|
23
|
+
else if (provider === 'gemini')
|
|
24
|
+
rate = 0.00001;
|
|
25
|
+
stats.cost += (amount * rate);
|
|
26
|
+
},
|
|
27
|
+
addMessage: () => {
|
|
28
|
+
stats.messages += 1;
|
|
29
|
+
},
|
|
30
|
+
getStats: () => {
|
|
31
|
+
return { ...stats, cost: Number(stats.cost.toFixed(4)) };
|
|
32
|
+
},
|
|
33
|
+
addEvent: (event, meta = {}) => {
|
|
34
|
+
eventLogs.unshift({ timestamp: formatTime(), event, meta });
|
|
35
|
+
if (eventLogs.length > MAX_LOGS)
|
|
36
|
+
eventLogs.pop();
|
|
37
|
+
},
|
|
38
|
+
addGatewayLog: (message, meta) => {
|
|
39
|
+
gatewayLogs.unshift({ timestamp: formatTime(), message, meta });
|
|
40
|
+
if (gatewayLogs.length > MAX_LOGS)
|
|
41
|
+
gatewayLogs.pop();
|
|
42
|
+
},
|
|
43
|
+
getLogs: () => {
|
|
44
|
+
return {
|
|
45
|
+
events: eventLogs,
|
|
46
|
+
gateway: gatewayLogs
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Logger = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const parser_1 = require("../config/parser");
|
|
9
|
+
const paths_1 = require("../config/paths");
|
|
10
|
+
class Logger {
|
|
11
|
+
logFilePath;
|
|
12
|
+
memory = [];
|
|
13
|
+
constructor() {
|
|
14
|
+
const config = (0, parser_1.loadConfig)();
|
|
15
|
+
this.logFilePath = (0, paths_1.getPath)(config.memory.path || 'memory.json');
|
|
16
|
+
this.loadMemory();
|
|
17
|
+
}
|
|
18
|
+
loadMemory() {
|
|
19
|
+
if (fs_1.default.existsSync(this.logFilePath)) {
|
|
20
|
+
try {
|
|
21
|
+
const data = fs_1.default.readFileSync(this.logFilePath, 'utf-8');
|
|
22
|
+
this.memory = JSON.parse(data);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error('Failed to read memory file. Starting fresh.');
|
|
26
|
+
this.memory = [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
saveMemory() {
|
|
31
|
+
try {
|
|
32
|
+
fs_1.default.writeFileSync(this.logFilePath, JSON.stringify(this.memory, null, 2));
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error('Failed to write memory file.');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
getHistory() {
|
|
39
|
+
return [...this.memory];
|
|
40
|
+
}
|
|
41
|
+
addEntry(entry) {
|
|
42
|
+
this.memory.push(entry);
|
|
43
|
+
this.saveMemory();
|
|
44
|
+
}
|
|
45
|
+
clear() {
|
|
46
|
+
this.memory = [];
|
|
47
|
+
this.saveMemory();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.Logger = Logger;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processUserInput = processUserInput;
|
|
4
|
+
const openai_1 = require("openai");
|
|
5
|
+
const parser_1 = require("../config/parser");
|
|
6
|
+
const logger_1 = require("../memory/logger");
|
|
7
|
+
const getBalance_1 = require("../web3/skills/getBalance");
|
|
8
|
+
const config = (0, parser_1.loadConfig)();
|
|
9
|
+
const logger = new logger_1.Logger();
|
|
10
|
+
// Initialize OpenAI client
|
|
11
|
+
const openai = new openai_1.OpenAI({
|
|
12
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
13
|
+
});
|
|
14
|
+
const systemPrompt = `You are an autonomous Web3 agent operating on EVM chains.
|
|
15
|
+
Your wallet address is available via the tools.
|
|
16
|
+
Always use the tools to interact with the blockchain.
|
|
17
|
+
If the user doesn't specify a chain, default to: ${config.agent.default_chain}.`;
|
|
18
|
+
async function processUserInput(input) {
|
|
19
|
+
// Add user input to memory
|
|
20
|
+
logger.addEntry({ role: 'user', content: input });
|
|
21
|
+
const history = logger.getHistory();
|
|
22
|
+
// Format messages for OpenAI
|
|
23
|
+
const messages = [
|
|
24
|
+
{ role: 'system', content: systemPrompt },
|
|
25
|
+
...history.map(m => {
|
|
26
|
+
const msg = { role: m.role, content: m.content || "" };
|
|
27
|
+
if (m.name)
|
|
28
|
+
msg.name = m.name;
|
|
29
|
+
if (m.tool_call_id)
|
|
30
|
+
msg.tool_call_id = m.tool_call_id;
|
|
31
|
+
if (m.tool_calls)
|
|
32
|
+
msg.tool_calls = m.tool_calls;
|
|
33
|
+
return msg;
|
|
34
|
+
})
|
|
35
|
+
];
|
|
36
|
+
try {
|
|
37
|
+
if (config.llm.provider !== 'openai') {
|
|
38
|
+
return `Provider ${config.llm.provider} is configured, but currently only OpenAI adapter is fully implemented in this demo.`;
|
|
39
|
+
}
|
|
40
|
+
const response = await openai.chat.completions.create({
|
|
41
|
+
model: config.llm.model,
|
|
42
|
+
temperature: config.llm.temperature,
|
|
43
|
+
messages: messages,
|
|
44
|
+
tools: [getBalance_1.getBalanceToolDefinition],
|
|
45
|
+
tool_choice: "auto",
|
|
46
|
+
});
|
|
47
|
+
const responseMessage = response.choices[0].message;
|
|
48
|
+
// Log assistant response
|
|
49
|
+
logger.addEntry({
|
|
50
|
+
role: 'assistant',
|
|
51
|
+
content: responseMessage.content || "",
|
|
52
|
+
tool_calls: responseMessage.tool_calls,
|
|
53
|
+
});
|
|
54
|
+
// Check if the model wants to call a tool
|
|
55
|
+
if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {
|
|
56
|
+
for (const toolCall of responseMessage.tool_calls) {
|
|
57
|
+
if (toolCall.function.name === 'get_balance') {
|
|
58
|
+
const args = JSON.parse(toolCall.function.arguments);
|
|
59
|
+
const balanceResult = await (0, getBalance_1.getBalance)(args.chainName, args.address);
|
|
60
|
+
logger.addEntry({
|
|
61
|
+
role: 'tool',
|
|
62
|
+
tool_call_id: toolCall.id,
|
|
63
|
+
name: toolCall.function.name,
|
|
64
|
+
content: balanceResult,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Second call to get the final answer after tool execution
|
|
69
|
+
const secondMessages = [
|
|
70
|
+
{ role: 'system', content: systemPrompt },
|
|
71
|
+
...logger.getHistory().map(m => {
|
|
72
|
+
const msg = { role: m.role, content: m.content || "" };
|
|
73
|
+
if (m.name)
|
|
74
|
+
msg.name = m.name;
|
|
75
|
+
if (m.tool_call_id)
|
|
76
|
+
msg.tool_call_id = m.tool_call_id;
|
|
77
|
+
if (m.tool_calls)
|
|
78
|
+
msg.tool_calls = m.tool_calls;
|
|
79
|
+
return msg;
|
|
80
|
+
})
|
|
81
|
+
];
|
|
82
|
+
const secondResponse = await openai.chat.completions.create({
|
|
83
|
+
model: config.llm.model,
|
|
84
|
+
messages: secondMessages,
|
|
85
|
+
});
|
|
86
|
+
const finalContent = secondResponse.choices[0].message.content || "";
|
|
87
|
+
logger.addEntry({ role: 'assistant', content: finalContent });
|
|
88
|
+
return finalContent;
|
|
89
|
+
}
|
|
90
|
+
return responseMessage.content || "No response generated.";
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error("LLM Error:", error);
|
|
94
|
+
return `Error connecting to AI Provider: ${error.message}`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadConfig = loadConfig;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
function loadConfig() {
|
|
11
|
+
const configPath = path_1.default.resolve(process.cwd(), 'config.yaml');
|
|
12
|
+
try {
|
|
13
|
+
const file = fs_1.default.readFileSync(configPath, 'utf8');
|
|
14
|
+
const parsed = yaml_1.default.parse(file);
|
|
15
|
+
return parsed;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.error('Failed to load config.yaml. Using default configuration.', error);
|
|
19
|
+
return {
|
|
20
|
+
agent: { name: 'OpenWeb-Default', default_chain: 'base' },
|
|
21
|
+
llm: { provider: 'openai', model: 'gpt-4o-mini', temperature: 0.2 },
|
|
22
|
+
memory: { type: 'file', path: './memory.json' }
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const readline_1 = __importDefault(require("readline"));
|
|
41
|
+
const reasoning_1 = require("../agent/reasoning");
|
|
42
|
+
const dotenv = __importStar(require("dotenv"));
|
|
43
|
+
const parser_1 = require("../config/parser");
|
|
44
|
+
dotenv.config();
|
|
45
|
+
const rl = readline_1.default.createInterface({
|
|
46
|
+
input: process.stdin,
|
|
47
|
+
output: process.stdout
|
|
48
|
+
});
|
|
49
|
+
const config = (0, parser_1.loadConfig)();
|
|
50
|
+
console.log(`================================`);
|
|
51
|
+
console.log(`š¤ OpenWeb CLI Agent Started`);
|
|
52
|
+
console.log(`š Agent Name: ${config.agent.name}`);
|
|
53
|
+
console.log(`š Default Chain: ${config.agent.default_chain}`);
|
|
54
|
+
console.log(`š§ AI Provider: ${config.llm.provider} (${config.llm.model})`);
|
|
55
|
+
console.log(`================================`);
|
|
56
|
+
console.log(`Type 'exit' or 'quit' to stop.\n`);
|
|
57
|
+
function ask() {
|
|
58
|
+
rl.question('š¤ You: ', async (input) => {
|
|
59
|
+
if (input.toLowerCase() === 'exit' || input.toLowerCase() === 'quit') {
|
|
60
|
+
console.log('Goodbye!');
|
|
61
|
+
rl.close();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (input.trim() === '') {
|
|
65
|
+
ask();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
console.log('š¤ Agent thinking...');
|
|
69
|
+
try {
|
|
70
|
+
const response = await (0, reasoning_1.processUserInput)(input);
|
|
71
|
+
console.log(`\nš¤ OpenWeb: ${response}\n`);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.log(`\nā Error: ${error.message}\n`);
|
|
75
|
+
}
|
|
76
|
+
ask();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
ask();
|