nyxora 1.5.4 → 1.5.6

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.
Files changed (46) hide show
  1. package/README.md +14 -7
  2. package/bin/nyxora.js +2 -0
  3. package/package.json +3 -2
  4. package/packages/core/package.json +1 -1
  5. package/packages/dashboard/package-lock.json +2 -2
  6. package/packages/dashboard/package.json +1 -1
  7. package/packages/policy/package.json +1 -1
  8. package/packages/signer/package.json +1 -1
  9. package/dist/agent/limitOrderManager.js +0 -177
  10. package/dist/agent/reasoning.js +0 -452
  11. package/dist/agent/transactionManager.js +0 -38
  12. package/dist/agent/updateProfile.js +0 -52
  13. package/dist/config/parser.js +0 -50
  14. package/dist/config/paths.js +0 -35
  15. package/dist/gateway/cli.js +0 -93
  16. package/dist/gateway/server.js +0 -215
  17. package/dist/gateway/setup.js +0 -246
  18. package/dist/gateway/telegram.js +0 -149
  19. package/dist/gateway/test.js +0 -15
  20. package/dist/gateway/tracker.js +0 -49
  21. package/dist/memory/logger.js +0 -109
  22. package/dist/system/pluginManager.js +0 -80
  23. package/dist/system/skills/browseWeb.js +0 -50
  24. package/dist/system/skills/executeShell.js +0 -38
  25. package/dist/system/skills/installSkill.js +0 -51
  26. package/dist/system/skills/readFile.js +0 -39
  27. package/dist/system/skills/updateSecurityPolicy.js +0 -60
  28. package/dist/system/skills/writeFile.js +0 -44
  29. package/dist/utils/crypto.js +0 -35
  30. package/dist/utils/formatter.js +0 -30
  31. package/dist/utils/state.js +0 -30
  32. package/dist/web3/config.js +0 -50
  33. package/dist/web3/skills/bridgeToken.js +0 -216
  34. package/dist/web3/skills/checkAddress.js +0 -52
  35. package/dist/web3/skills/checkPortfolio.js +0 -154
  36. package/dist/web3/skills/checkSecurity.js +0 -67
  37. package/dist/web3/skills/createWallet.js +0 -34
  38. package/dist/web3/skills/customTx.js +0 -93
  39. package/dist/web3/skills/getBalance.js +0 -117
  40. package/dist/web3/skills/getMyAddress.js +0 -29
  41. package/dist/web3/skills/getPrice.js +0 -44
  42. package/dist/web3/skills/marketAnalysis.js +0 -71
  43. package/dist/web3/skills/mintNft.js +0 -122
  44. package/dist/web3/skills/swapToken.js +0 -217
  45. package/dist/web3/skills/transfer.js +0 -131
  46. package/dist/web3/utils/tokens.js +0 -110
@@ -1,452 +0,0 @@
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
- exports.processUserInput = processUserInput;
8
- const fs_1 = __importDefault(require("fs"));
9
- const openai_1 = require("openai");
10
- const parser_1 = require("../config/parser");
11
- const logger_1 = require("../memory/logger");
12
- const tracker_1 = require("../gateway/tracker");
13
- const getBalance_1 = require("../web3/skills/getBalance");
14
- const transfer_1 = require("../web3/skills/transfer");
15
- const getPrice_1 = require("../web3/skills/getPrice");
16
- const swapToken_1 = require("../web3/skills/swapToken");
17
- const bridgeToken_1 = require("../web3/skills/bridgeToken");
18
- const mintNft_1 = require("../web3/skills/mintNft");
19
- const customTx_1 = require("../web3/skills/customTx");
20
- const createWallet_1 = require("../web3/skills/createWallet");
21
- const checkSecurity_1 = require("../web3/skills/checkSecurity");
22
- const marketAnalysis_1 = require("../web3/skills/marketAnalysis");
23
- const checkPortfolio_1 = require("../web3/skills/checkPortfolio");
24
- const checkAddress_1 = require("../web3/skills/checkAddress");
25
- const getMyAddress_1 = require("../web3/skills/getMyAddress");
26
- const limitOrderManager_1 = require("./limitOrderManager");
27
- const updateProfile_1 = require("./updateProfile");
28
- const updateSecurityPolicy_1 = require("../system/skills/updateSecurityPolicy");
29
- const readFile_1 = require("../system/skills/readFile");
30
- const writeFile_1 = require("../system/skills/writeFile");
31
- const executeShell_1 = require("../system/skills/executeShell");
32
- const browseWeb_1 = require("../system/skills/browseWeb");
33
- const installSkill_1 = require("../system/skills/installSkill");
34
- const pluginManager_1 = require("../system/pluginManager");
35
- const paths_1 = require("../config/paths");
36
- const picocolors_1 = __importDefault(require("picocolors"));
37
- exports.logger = new logger_1.Logger();
38
- let currentKeyIndex = 0;
39
- function getOpenAI() {
40
- const config = (0, parser_1.loadConfig)();
41
- if (config.llm.provider === 'ollama') {
42
- return new openai_1.OpenAI({
43
- baseURL: process.env.OLLAMA_BASE_URL ? `${process.env.OLLAMA_BASE_URL}/v1` : 'http://localhost:11434/v1',
44
- apiKey: 'ollama', // API key is not required for local Ollama
45
- });
46
- }
47
- // Get API key from config (UI) or fallback to .env
48
- let apiKey = '';
49
- let configuredKeys = config.llm.api_keys;
50
- if (typeof configuredKeys === 'string') {
51
- configuredKeys = [configuredKeys];
52
- }
53
- if (Array.isArray(configuredKeys) && configuredKeys.length > 0) {
54
- // Filter out empty keys
55
- const keys = configuredKeys.filter(k => typeof k === 'string' && k.trim() !== '');
56
- if (keys.length > 0) {
57
- currentKeyIndex = currentKeyIndex % keys.length;
58
- apiKey = keys[currentKeyIndex];
59
- console.log(`[LLM] Using rotated API Key (${currentKeyIndex + 1}/${keys.length}): ${apiKey.substring(0, 4)}...`);
60
- currentKeyIndex++; // Increment for next request
61
- }
62
- }
63
- // Fallbacks if no valid keys found in config.llm.api_keys
64
- if (!apiKey) {
65
- if (config.llm.provider === 'gemini') {
66
- apiKey = config.llm.credentials?.gemini_key || '';
67
- }
68
- else if (config.llm.provider === 'openrouter') {
69
- apiKey = config.llm.credentials?.openrouter_key || '';
70
- }
71
- else {
72
- apiKey = config.llm.credentials?.openai_key || '';
73
- }
74
- if (!apiKey) {
75
- throw new Error(`No API Key found for ${config.llm.provider} in config.yaml. Please run 'nyxora setup' to configure it.`);
76
- }
77
- console.log(`[LLM] Using default API Key from config.yaml`);
78
- }
79
- if (config.llm.provider === 'gemini') {
80
- return new openai_1.OpenAI({
81
- baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai/',
82
- apiKey: apiKey,
83
- });
84
- }
85
- else if (config.llm.provider === 'openrouter') {
86
- return new openai_1.OpenAI({
87
- baseURL: 'https://openrouter.ai/api/v1',
88
- apiKey: apiKey,
89
- });
90
- }
91
- else {
92
- return new openai_1.OpenAI({
93
- apiKey: apiKey,
94
- });
95
- }
96
- }
97
- async function executeWithRetry(requestBuilder, maxRetries = 3) {
98
- let retries = 0;
99
- while (retries <= maxRetries) {
100
- try {
101
- const client = getOpenAI();
102
- return await requestBuilder(client);
103
- }
104
- catch (error) {
105
- const status = error?.status || error?.response?.status;
106
- // 401 Unauthorized or 400 Bad Request - don't retry, it's fatal
107
- if (status === 401 || status === 400) {
108
- console.error(`[LLM] Fatal Error ${status}: ${error.message}. Aborting.`);
109
- throw error;
110
- }
111
- // 429 Rate Limit - rotate provider/key immediately and retry
112
- if (status === 429) {
113
- console.warn(`[LLM] Rate Limit (429) hit. Rotating key...`);
114
- // getOpenAI() automatically rotates to next key if available
115
- retries++;
116
- if (retries > maxRetries)
117
- throw error;
118
- continue; // Try next key immediately
119
- }
120
- // 500, 502, 503, Timeout, Network error - Exponential Backoff
121
- retries++;
122
- if (retries > maxRetries) {
123
- console.error(`[LLM] Max retries reached.`);
124
- throw error;
125
- }
126
- const delayMs = Math.pow(2, retries) * 1000; // 2s, 4s, 8s
127
- console.warn(`[LLM] API Error (${status || error.message}). Retrying in ${delayMs}ms...`);
128
- await new Promise(resolve => setTimeout(resolve, delayMs));
129
- }
130
- }
131
- }
132
- function getSystemPrompt() {
133
- const config = (0, parser_1.loadConfig)();
134
- let basePrompt = `You are an autonomous Web3 agent operating on EVM chains.
135
- You are equipped with a native wallet.
136
- CRITICAL RULE: You must always reply in the exact same language that the user uses to talk to you. If the user speaks Indonesian, reply in Indonesian. If they speak English, reply in English.
137
- CRITICAL RULE: If the user asks to check "my balance", "saldo saya", or anything about their own wallet, DO NOT ask them for an address. You must immediately call the get_balance tool and LEAVE THE ADDRESS PARAMETER EMPTY. The system will automatically use the injected private key wallet.
138
- Always use the tools to interact with the blockchain.
139
- If the user doesn't specify a chain, default to: ${config.agent.default_chain}.`;
140
- // Read IDENTITY.md for core AI persona
141
- try {
142
- const identityMdPath = (0, paths_1.getPath)('IDENTITY.md');
143
- if (fs_1.default.existsSync(identityMdPath)) {
144
- const identityInstructions = fs_1.default.readFileSync(identityMdPath, 'utf8');
145
- basePrompt += `\n\n--- CORE IDENTITY & PERSONA ---\n${identityInstructions}`;
146
- }
147
- }
148
- catch (error) {
149
- console.error('Failed to read IDENTITY.md:', error);
150
- }
151
- // Read user.md for custom instructions
152
- try {
153
- const userMdPath = (0, paths_1.getPath)('user.md');
154
- if (fs_1.default.existsSync(userMdPath)) {
155
- const customInstructions = fs_1.default.readFileSync(userMdPath, 'utf8');
156
- basePrompt += `\n\n--- CUSTOM USER INSTRUCTIONS ---\n${customInstructions}`;
157
- }
158
- }
159
- catch (error) {
160
- console.error('Failed to read user.md:', error);
161
- }
162
- // Read security_policy.md for NLP security constraints
163
- try {
164
- const policyPath = (0, paths_1.getPath)('security_policy.md');
165
- if (fs_1.default.existsSync(policyPath)) {
166
- const securityInstructions = fs_1.default.readFileSync(policyPath, 'utf8');
167
- basePrompt += `\n\n--- SECURITY POLICY (MANDATORY RULES) ---\n${securityInstructions}\n\nCRITICAL: If the user asks you to perform an action that violates the Security Policy above, YOU MUST NOT EXECUTE IT DIRECTLY. Instead, ask for their explicit permission first.`;
168
- }
169
- }
170
- catch (error) {
171
- console.error('Failed to read security_policy.md:', error);
172
- }
173
- return basePrompt;
174
- }
175
- async function processUserInput(input, role = 'user', onProgress) {
176
- const config = (0, parser_1.loadConfig)();
177
- // Add input to memory
178
- exports.logger.addEntry({ role, content: input });
179
- const history = exports.logger.getHistory();
180
- // Format messages for OpenAI
181
- const messages = [
182
- { role: 'system', content: getSystemPrompt() },
183
- ...history
184
- .filter(m => !(m.role === 'tool' && !m.tool_call_id))
185
- .map(m => {
186
- let role = m.role;
187
- if (role === 'system')
188
- role = 'user';
189
- const msg = { role, content: m.content || "" };
190
- if (m.name)
191
- msg.name = m.name;
192
- if (m.tool_call_id)
193
- msg.tool_call_id = m.tool_call_id;
194
- if (m.tool_calls)
195
- msg.tool_calls = m.tool_calls;
196
- return msg;
197
- })
198
- ];
199
- try {
200
- if (config.llm.provider !== 'openai' && config.llm.provider !== 'ollama' && config.llm.provider !== 'gemini' && config.llm.provider !== 'openrouter') {
201
- return `Provider ${config.llm.provider} is configured, but currently only OpenAI, OpenRouter, Ollama, and Gemini adapters are implemented.`;
202
- }
203
- const response = await executeWithRetry(async (client) => {
204
- return await client.chat.completions.create({
205
- model: config.llm.model,
206
- temperature: config.llm.temperature,
207
- messages: messages,
208
- tools: [
209
- getBalance_1.getBalanceToolDefinition,
210
- transfer_1.transferToolDefinition,
211
- getPrice_1.getPriceToolDefinition,
212
- swapToken_1.swapTokenToolDefinition,
213
- bridgeToken_1.bridgeTokenToolDefinition,
214
- mintNft_1.mintNftToolDefinition,
215
- customTx_1.customTxToolDefinition,
216
- createWallet_1.createWalletToolDefinition,
217
- checkSecurity_1.checkSecurityToolDefinition,
218
- marketAnalysis_1.marketAnalysisToolDefinition,
219
- checkPortfolio_1.checkPortfolioToolDefinition,
220
- checkAddress_1.checkAddressToolDefinition,
221
- getMyAddress_1.getMyAddressToolDefinition,
222
- limitOrderManager_1.createLimitOrderToolDefinition,
223
- limitOrderManager_1.listLimitOrdersToolDefinition,
224
- limitOrderManager_1.cancelLimitOrderToolDefinition,
225
- updateProfile_1.updateProfileToolDefinition,
226
- updateSecurityPolicy_1.updateSecurityPolicyToolDefinition,
227
- readFile_1.readLocalFileToolDefinition,
228
- writeFile_1.writeLocalFileToolDefinition,
229
- executeShell_1.runTerminalCommandToolDefinition,
230
- browseWeb_1.browseWebsiteToolDefinition,
231
- installSkill_1.installExternalSkillToolDefinition,
232
- ...pluginManager_1.pluginManager.getToolDefinitions()
233
- ],
234
- tool_choice: "auto",
235
- });
236
- });
237
- const responseMessage = response.choices[0].message;
238
- // Log tracking
239
- tracker_1.Tracker.addMessage();
240
- if (response.usage?.total_tokens) {
241
- tracker_1.Tracker.addTokens(response.usage.total_tokens, config.llm.provider);
242
- }
243
- tracker_1.Tracker.addEvent('llm.response', { provider: config.llm.provider, tool_calls: responseMessage.tool_calls?.length || 0 });
244
- // Log assistant response
245
- exports.logger.addEntry({
246
- role: 'assistant',
247
- content: responseMessage.content || "",
248
- tool_calls: responseMessage.tool_calls,
249
- });
250
- // Check if the model wants to call a tool
251
- if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {
252
- for (const _toolCall of responseMessage.tool_calls) {
253
- const toolCall = _toolCall;
254
- let result = "";
255
- const args = JSON.parse(toolCall.function.arguments);
256
- const toolName = toolCall.function.name;
257
- console.log(picocolors_1.default.yellow(`[⚡ Eksekusi Tool] AI memanggil ${toolName}...`));
258
- if (onProgress)
259
- onProgress(`_⚡ Menjalankan alat: ${toolName}..._`);
260
- try {
261
- switch (toolName) {
262
- case 'get_balance': {
263
- result = await (0, getBalance_1.getBalance)(args.chainName, args.address, args.token);
264
- break;
265
- }
266
- case 'transfer_token':
267
- case 'transfer_native': {
268
- if (config.permissions?.web3?.allow_transfer === false) {
269
- result = `[Security Blocked] Runtime Permission Denied: Web3 transfers are disabled. Update config.yaml to allow.`;
270
- break;
271
- }
272
- result = await (0, transfer_1.prepareTransfer)(args.chainName, args.toAddress, args.amountStr || args.amountEth, args.token);
273
- break;
274
- }
275
- case 'get_price': {
276
- result = await (0, getPrice_1.getPrice)(args.coinId);
277
- break;
278
- }
279
- case 'swap_token': {
280
- if (config.permissions?.web3?.allow_swap === false) {
281
- result = `[Security Blocked] Runtime Permission Denied: Web3 swaps are disabled. Update config.yaml to allow.`;
282
- break;
283
- }
284
- // Note: max_usd_per_tx validation would ideally be calculated here before prepareSwapToken
285
- result = await (0, swapToken_1.prepareSwapToken)(args.chainName, args.fromToken, args.toToken, args.amountStr || args.amount, args.mode, args.providerName);
286
- break;
287
- }
288
- case 'bridge_token': {
289
- if (config.permissions?.web3?.allow_transfer === false) {
290
- result = `[Security Blocked] Runtime Permission Denied: Web3 bridging (transfer) is disabled. Update config.yaml to allow.`;
291
- break;
292
- }
293
- result = await (0, bridgeToken_1.prepareBridgeToken)(args.fromChainName, args.toChainName, args.fromToken, args.toToken, args.amountStr, args.mode, args.providerName);
294
- break;
295
- }
296
- case 'mint_nft': {
297
- result = await (0, mintNft_1.prepareMintNft)(args.chainName, args.contractAddress, args.functionSignature, args.argsStr, args.valueEth);
298
- break;
299
- }
300
- case 'custom_tx': {
301
- if (config.permissions?.web3?.allow_transfer === false) {
302
- result = `[Security Blocked] Runtime Permission Denied: Custom transactions are blocked because transfers are disabled.`;
303
- break;
304
- }
305
- result = await (0, customTx_1.prepareCustomTx)(args.chainName, args.toAddress, args.dataHex, args.valueEth, args.gasLimitStr);
306
- break;
307
- }
308
- case 'create_wallet': {
309
- result = await (0, createWallet_1.createWallet)();
310
- break;
311
- }
312
- case 'check_token_security': {
313
- result = await (0, checkSecurity_1.checkTokenSecurity)(args.chainName, args.contractAddress);
314
- break;
315
- }
316
- case 'analyze_market': {
317
- result = await (0, marketAnalysis_1.analyzeMarket)(args.chainName, args.tokenAddressOrSymbol);
318
- break;
319
- }
320
- case 'check_portfolio': {
321
- result = await (0, checkPortfolio_1.checkPortfolio)(args.chainName, args.address);
322
- break;
323
- }
324
- case 'check_address': {
325
- result = await (0, checkAddress_1.checkAddress)(args.chainName, args.address);
326
- break;
327
- }
328
- case 'get_my_address': {
329
- result = await (0, getMyAddress_1.getMyAddress)();
330
- break;
331
- }
332
- case 'create_limit_order': {
333
- if (config.permissions?.web3?.allow_swap === false) {
334
- result = `[Security Blocked] Runtime Permission Denied: Limit orders require swap permissions. Update config.yaml to allow.`;
335
- break;
336
- }
337
- result = limitOrderManager_1.limitOrderManager.createOrder(args.chainName, args.fromToken, args.toToken, args.amountStr, args.targetPriceUsd, args.condition);
338
- break;
339
- }
340
- case 'list_limit_orders': {
341
- result = limitOrderManager_1.limitOrderManager.listOrders();
342
- break;
343
- }
344
- case 'cancel_limit_order': {
345
- result = limitOrderManager_1.limitOrderManager.cancelOrder(args.id);
346
- break;
347
- }
348
- case 'update_profile': {
349
- result = (0, updateProfile_1.updateProfile)(args.content, args.mode);
350
- break;
351
- }
352
- case 'update_security_policy': {
353
- result = (0, updateSecurityPolicy_1.updateSecurityPolicy)(args.rule, args.action);
354
- break;
355
- }
356
- case 'read_local_file': {
357
- result = (0, readFile_1.readLocalFile)(args.filePath);
358
- break;
359
- }
360
- case 'write_local_file': {
361
- if (config.permissions?.system?.allow_file_write === false) {
362
- result = `[Security Blocked] Runtime Permission Denied: File writing is disabled. Update config.yaml to allow.`;
363
- break;
364
- }
365
- result = (0, writeFile_1.writeLocalFile)(args.filePath, args.content);
366
- break;
367
- }
368
- case 'run_terminal_command': {
369
- if (config.permissions?.system?.allow_shell_execution === false) {
370
- result = `[Security Blocked] Runtime Permission Denied: Shell execution is disabled. Update config.yaml to allow.`;
371
- break;
372
- }
373
- result = await (0, executeShell_1.runTerminalCommand)(args.command);
374
- break;
375
- }
376
- case 'browse_website': {
377
- result = await (0, browseWeb_1.browseWebsite)(args.url);
378
- break;
379
- }
380
- case 'install_external_skill': {
381
- result = await (0, installSkill_1.installExternalSkill)(args.url);
382
- break;
383
- }
384
- default: {
385
- const externalResult = await pluginManager_1.pluginManager.executeTool(toolName, args);
386
- if (externalResult !== null) {
387
- result = externalResult;
388
- }
389
- else {
390
- result = `Error: Tool ${toolName} is not implemented.`;
391
- }
392
- break;
393
- }
394
- }
395
- if (result.includes('[Security Blocked]') || result.startsWith('Error:')) {
396
- console.log(picocolors_1.default.red(`[❌ Gagal] Tool ${toolName} mengembalikan error atau diblokir.`));
397
- }
398
- else {
399
- console.log(picocolors_1.default.green(`[✅ Sukses] Tool ${toolName} berhasil dieksekusi.`));
400
- }
401
- }
402
- catch (toolError) {
403
- result = `Error executing ${toolName}: ${toolError.message}`;
404
- console.log(picocolors_1.default.red(`[❌ Error Crash] Eksekusi ${toolName} gagal total: ${toolError.message}`));
405
- }
406
- exports.logger.addEntry({
407
- role: 'tool',
408
- tool_call_id: toolCall.id,
409
- name: toolName,
410
- content: result,
411
- });
412
- }
413
- // Second call to get the final answer after tool execution
414
- const secondMessages = [
415
- { role: 'system', content: getSystemPrompt() },
416
- ...exports.logger.getHistory()
417
- .filter(m => !(m.role === 'tool' && !m.tool_call_id))
418
- .map(m => {
419
- let role = m.role;
420
- if (role === 'system')
421
- role = 'user';
422
- const msg = { role, content: m.content || "" };
423
- if (m.name)
424
- msg.name = m.name;
425
- if (m.tool_call_id)
426
- msg.tool_call_id = m.tool_call_id;
427
- if (m.tool_calls)
428
- msg.tool_calls = m.tool_calls;
429
- return msg;
430
- })
431
- ];
432
- const secondResponse = await executeWithRetry(async (client) => {
433
- return await client.chat.completions.create({
434
- model: config.llm.model,
435
- messages: secondMessages,
436
- });
437
- });
438
- if (secondResponse.usage?.total_tokens) {
439
- tracker_1.Tracker.addTokens(secondResponse.usage.total_tokens, config.llm.provider);
440
- }
441
- tracker_1.Tracker.addEvent('llm.final_response', { provider: config.llm.provider });
442
- const finalContent = secondResponse.choices[0].message.content || "";
443
- exports.logger.addEntry({ role: 'assistant', content: finalContent });
444
- return finalContent;
445
- }
446
- return responseMessage.content || "No response generated.";
447
- }
448
- catch (error) {
449
- console.error("LLM Error:", error);
450
- return `Error connecting to AI Provider: ${error.message}`;
451
- }
452
- }
@@ -1,38 +0,0 @@
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.txManager = void 0;
7
- const crypto_1 = __importDefault(require("crypto"));
8
- class TransactionManager {
9
- transactions = new Map();
10
- createPendingTransaction(type, chainName, details) {
11
- const id = crypto_1.default.randomUUID();
12
- const tx = {
13
- id,
14
- type,
15
- chainName,
16
- details,
17
- status: 'pending',
18
- createdAt: Date.now(),
19
- };
20
- this.transactions.set(id, tx);
21
- return tx;
22
- }
23
- getPending() {
24
- return Array.from(this.transactions.values()).filter(t => t.status === 'pending');
25
- }
26
- getTransaction(id) {
27
- return this.transactions.get(id);
28
- }
29
- updateStatus(id, status, result) {
30
- const tx = this.transactions.get(id);
31
- if (tx) {
32
- tx.status = status;
33
- if (result)
34
- tx.result = result;
35
- }
36
- }
37
- }
38
- exports.txManager = new TransactionManager();
@@ -1,52 +0,0 @@
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.updateProfileToolDefinition = void 0;
7
- exports.updateProfile = updateProfile;
8
- const fs_1 = __importDefault(require("fs"));
9
- const paths_1 = require("../config/paths");
10
- function updateProfile(content, mode) {
11
- try {
12
- const userMdPath = (0, paths_1.getPath)('user.md');
13
- if (mode === 'replace') {
14
- fs_1.default.writeFileSync(userMdPath, content, 'utf8');
15
- return "Profile replaced successfully. New user.md has been saved.";
16
- }
17
- else {
18
- let existingContent = "";
19
- if (fs_1.default.existsSync(userMdPath)) {
20
- existingContent = fs_1.default.readFileSync(userMdPath, 'utf8');
21
- }
22
- const newContent = existingContent + "\n" + content;
23
- fs_1.default.writeFileSync(userMdPath, newContent, 'utf8');
24
- return "Profile appended successfully. New instructions added to user.md.";
25
- }
26
- }
27
- catch (error) {
28
- return `Failed to update profile: ${error.message}`;
29
- }
30
- }
31
- exports.updateProfileToolDefinition = {
32
- type: "function",
33
- function: {
34
- name: "update_profile",
35
- description: "Updates or rewrites the user.md file. Use this when the user asks you to remember something about them, change their persona, or update your instructions.",
36
- parameters: {
37
- type: "object",
38
- properties: {
39
- content: {
40
- type: "string",
41
- description: "The content to write or append to user.md",
42
- },
43
- mode: {
44
- type: "string",
45
- enum: ["append", "replace"],
46
- description: "Whether to append the content to the existing file or replace the entire file.",
47
- }
48
- },
49
- required: ["content", "mode"],
50
- },
51
- },
52
- };
@@ -1,50 +0,0 @@
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
- exports.saveConfig = saveConfig;
8
- const fs_1 = __importDefault(require("fs"));
9
- const yaml_1 = __importDefault(require("yaml"));
10
- const paths_1 = require("./paths");
11
- function loadConfig() {
12
- const configPath = (0, paths_1.getPath)('config.yaml');
13
- try {
14
- const file = fs_1.default.readFileSync(configPath, 'utf8');
15
- const parsed = yaml_1.default.parse(file);
16
- return parsed;
17
- }
18
- catch (error) {
19
- console.error('Failed to load config.yaml. Using default configuration.', error);
20
- return {
21
- agent: { name: 'Nyxora-Default', default_chain: 'base' },
22
- llm: {
23
- provider: 'openai',
24
- model: 'gpt-4o-mini',
25
- temperature: 0.2,
26
- api_keys: [],
27
- credentials: {}
28
- },
29
- memory: { type: 'file', path: './memory.json' },
30
- web3: { rpc_urls: {} },
31
- integrations: {
32
- telegram: { enabled: false }
33
- },
34
- permissions: {
35
- web3: { allow_transfer: false, allow_swap: true, max_usd_per_tx: 50 },
36
- system: { allow_shell_execution: false, allow_file_write: false }
37
- }
38
- };
39
- }
40
- }
41
- function saveConfig(newConfig) {
42
- const configPath = (0, paths_1.getPath)('config.yaml');
43
- try {
44
- const yamlStr = yaml_1.default.stringify(newConfig);
45
- fs_1.default.writeFileSync(configPath, yamlStr, 'utf8');
46
- }
47
- catch (error) {
48
- console.error('Failed to save config.yaml', error);
49
- }
50
- }
@@ -1,35 +0,0 @@
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.getAppDir = getAppDir;
7
- exports.getPath = getPath;
8
- const fs_1 = __importDefault(require("fs"));
9
- const path_1 = __importDefault(require("path"));
10
- const os_1 = __importDefault(require("os"));
11
- let isGlobalModeCache = null;
12
- function getAppDir() {
13
- // Check if .env or config.yaml exists in current working directory
14
- if (isGlobalModeCache === null) {
15
- const localEnv = path_1.default.join(process.cwd(), '.env');
16
- const localConfig = path_1.default.join(process.cwd(), 'config.yaml');
17
- if (fs_1.default.existsSync(localEnv) || fs_1.default.existsSync(localConfig)) {
18
- isGlobalModeCache = false; // Local manual mode
19
- }
20
- else {
21
- isGlobalModeCache = true; // Global CLI mode
22
- }
23
- }
24
- if (isGlobalModeCache) {
25
- const globalDir = path_1.default.join(os_1.default.homedir(), '.nyxora');
26
- if (!fs_1.default.existsSync(globalDir)) {
27
- fs_1.default.mkdirSync(globalDir, { recursive: true });
28
- }
29
- return globalDir;
30
- }
31
- return process.cwd();
32
- }
33
- function getPath(filename) {
34
- return path_1.default.join(getAppDir(), filename);
35
- }