nyxora 26.6.9 → 26.6.11-2
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 +22 -3
- package/dist/launcher.js +3 -0
- package/dist/packages/core/src/agent/limitOrderManager.js +19 -73
- package/dist/packages/core/src/agent/reasoning.js +113 -50
- package/dist/packages/core/src/config/defiConfigManager.js +36 -0
- package/dist/packages/core/src/config/parser.js +2 -2
- package/dist/packages/core/src/gateway/cli.js +15 -2
- package/dist/packages/core/src/gateway/server.js +175 -24
- package/dist/packages/core/src/gateway/setup.js +162 -64
- package/dist/packages/core/src/gateway/telegram.js +42 -27
- package/dist/packages/core/src/memory/episodic.js +78 -0
- package/dist/packages/core/src/memory/promotionEngine.js +67 -0
- package/dist/packages/core/src/memory/reflection.js +97 -0
- package/dist/packages/core/src/memory/validator.js +66 -0
- package/dist/packages/core/src/system/skills/analyzeDocument.js +79 -2
- package/dist/packages/core/src/system/skills/audioTranscribe.js +45 -0
- package/dist/packages/core/src/system/skills/browseWeb.js +58 -18
- package/dist/packages/core/src/system/skills/editFile.js +57 -0
- package/dist/packages/core/src/system/skills/executeShell.js +29 -0
- package/dist/packages/core/src/system/skills/generateExcel.js +59 -0
- package/dist/packages/core/src/system/skills/gitManager.js +91 -0
- package/dist/packages/core/src/system/skills/notionWorkspace.js +80 -0
- package/dist/packages/core/src/system/skills/readFile.js +47 -3
- package/dist/packages/core/src/system/skills/summarizeText.js +53 -0
- package/dist/packages/core/src/system/skills/xManager.js +78 -0
- package/dist/packages/core/src/test-all-routers.js +10 -3
- package/dist/packages/core/src/test-router.js +14 -13
- package/dist/packages/core/src/test_security.js +43 -0
- package/dist/packages/core/src/utils/formatter.js +46 -10
- package/dist/packages/core/src/utils/httpClient.js +88 -0
- package/dist/packages/core/src/utils/userWhitelistManager.js +66 -11
- package/dist/packages/core/src/web3/aggregator/aggregatorMainnet.js +253 -0
- package/dist/packages/core/src/web3/aggregator/aggregatorTestnet.js +105 -0
- package/dist/packages/core/src/web3/aggregator/defiRouter.js +38 -0
- package/dist/packages/core/src/web3/config.js +18 -105
- package/dist/packages/core/src/web3/skills/autonomousDefi.js +191 -0
- package/dist/packages/core/src/web3/skills/bridgeToken.js +62 -278
- package/dist/packages/core/src/web3/skills/checkPortfolio.js +2 -2
- package/dist/packages/core/src/web3/skills/checkRegistryStatus.js +79 -0
- package/dist/packages/core/src/web3/skills/checkSecurity.js +2 -5
- package/dist/packages/core/src/web3/skills/customTx.js +28 -90
- package/dist/packages/core/src/web3/skills/defiLending.js +121 -0
- package/dist/packages/core/src/web3/skills/executeDefi.js +156 -0
- package/dist/packages/core/src/web3/skills/getPrice.js +11 -12
- package/dist/packages/core/src/web3/skills/getTxHistory.js +111 -0
- package/dist/packages/core/src/web3/skills/limitOrder.js +106 -0
- package/dist/packages/core/src/web3/skills/marketAnalysis.js +16 -25
- package/dist/packages/core/src/web3/skills/mintNft.js +15 -29
- package/dist/packages/core/src/web3/skills/provideLiquidity.js +177 -0
- package/dist/packages/core/src/web3/skills/revokeApprovals.js +100 -0
- package/dist/packages/core/src/web3/skills/swapToken.js +38 -280
- package/dist/packages/core/src/web3/skills/transfer.js +39 -34
- package/dist/packages/core/src/web3/skills/yieldVault.js +119 -0
- package/dist/packages/core/src/web3/utils/chains.js +17 -0
- package/dist/packages/core/src/web3/utils/marketEngine.js +88 -0
- package/dist/packages/core/src/web3/utils/portfolioNormalizer.js +73 -0
- package/dist/packages/core/src/web3/utils/protocolRegistry.js +46 -0
- package/dist/packages/core/src/web3/utils/rpcEngine.js +132 -0
- package/dist/packages/core/src/web3/utils/tokens.js +45 -15
- package/dist/packages/core/src/web3/utils/vaultClient.js +69 -0
- package/dist/packages/core/src/web3/utils/zerionTracker.js +59 -0
- package/dist/packages/policy/src/server.js +31 -4
- package/dist/packages/signer/src/server.js +23 -18
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/launcher.ts +153 -0
- package/package.json +37 -3
- package/packages/core/package.json +7 -2
- package/packages/core/src/__tests__/reasoning.test.ts +81 -0
- package/packages/core/src/__tests__/tokens.test.ts +55 -0
- package/packages/core/src/__tests__/web3.test.ts +50 -0
- package/packages/core/src/agent/reasoning.d.ts.map +1 -0
- package/packages/core/src/agent/reasoning.ts +160 -51
- package/packages/core/src/agent/transactionManager.ts +1 -1
- package/packages/core/src/config/defiConfigManager.ts +40 -0
- package/packages/core/src/config/parser.d.ts.map +1 -0
- package/packages/core/src/config/parser.ts +11 -3
- package/packages/core/src/gateway/cli.d.ts.map +1 -0
- package/packages/core/src/gateway/cli.ts +12 -2
- package/packages/core/src/gateway/server.ts +176 -24
- package/packages/core/src/gateway/setup.ts +167 -66
- package/packages/core/src/gateway/telegram.ts +41 -28
- package/packages/core/src/memory/episodic.ts +92 -0
- package/packages/core/src/memory/logger.d.ts.map +1 -0
- package/packages/core/src/memory/promotionEngine.ts +69 -0
- package/packages/core/src/memory/reflection.ts +99 -0
- package/packages/core/src/memory/validator.ts +70 -0
- package/packages/core/src/system/skills/analyzeDocument.ts +54 -2
- package/packages/core/src/system/skills/audioTranscribe.ts +42 -0
- package/packages/core/src/system/skills/browseWeb.ts +69 -19
- package/packages/core/src/system/skills/editFile.ts +56 -0
- package/packages/core/src/system/skills/executeShell.ts +35 -0
- package/packages/core/src/system/skills/generateExcel.ts +60 -0
- package/packages/core/src/system/skills/gitManager.ts +84 -0
- package/packages/core/src/system/skills/notionWorkspace.ts +78 -0
- package/packages/core/src/system/skills/readFile.ts +54 -3
- package/packages/core/src/system/skills/summarizeText.ts +54 -0
- package/packages/core/src/system/skills/xManager.ts +76 -0
- package/packages/core/src/test-all-routers.ts +59 -0
- package/packages/core/src/test-router.ts +49 -0
- package/packages/core/src/test_security.ts +45 -0
- package/packages/core/src/utils/formatter.ts +38 -10
- package/packages/core/src/utils/httpClient.ts +108 -0
- package/packages/core/src/utils/userWhitelistManager.ts +79 -13
- package/packages/core/src/web3/aggregator/aggregatorMainnet.ts +284 -0
- package/packages/core/src/web3/aggregator/aggregatorTestnet.ts +124 -0
- package/packages/core/src/web3/aggregator/defiRouter.ts +38 -0
- package/packages/core/src/web3/config.d.ts.map +1 -0
- package/packages/core/src/web3/config.ts +4 -101
- package/packages/core/src/web3/skills/bridgeToken.ts +72 -266
- package/packages/core/src/web3/skills/checkPortfolio.ts +2 -2
- package/packages/core/src/web3/skills/checkRegistryStatus.ts +85 -0
- package/packages/core/src/web3/skills/checkSecurity.ts +3 -6
- package/packages/core/src/web3/skills/customTx.ts +35 -103
- package/packages/core/src/web3/skills/defiLending.ts +128 -0
- package/packages/core/src/web3/skills/executeDefi.ts +168 -0
- package/packages/core/src/web3/skills/getBalance.d.ts.map +1 -0
- package/packages/core/src/web3/skills/getPrice.ts +13 -12
- package/packages/core/src/web3/skills/getTxHistory.ts +120 -0
- package/packages/core/src/web3/skills/marketAnalysis.ts +15 -25
- package/packages/core/src/web3/skills/mintNft.ts +17 -33
- package/packages/core/src/web3/skills/provideLiquidity.ts +202 -0
- package/packages/core/src/web3/skills/revokeApprovals.ts +106 -0
- package/packages/core/src/web3/skills/swapToken.ts +53 -271
- package/packages/core/src/web3/skills/transfer.ts +40 -38
- package/packages/core/src/web3/skills/yieldVault.ts +124 -0
- package/packages/core/src/web3/utils/chains.ts +17 -0
- package/packages/core/src/web3/utils/marketEngine.ts +90 -0
- package/packages/core/src/web3/utils/portfolioNormalizer.ts +97 -0
- package/packages/core/src/web3/utils/rpcEngine.ts +120 -0
- package/packages/core/src/web3/utils/tokens.ts +43 -15
- package/packages/core/src/web3/utils/vaultClient.ts +63 -0
- package/packages/core/src/web3/utils/zerionTracker.ts +77 -0
- package/packages/dashboard/dist/assets/index-CCgm_N9M.js +13 -0
- package/packages/dashboard/dist/assets/index-DnQrbB4c.css +1 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package.json +3 -3
- package/packages/mcp-server/package.json +1 -1
- package/packages/mcp-server/src/server.ts +8 -10
- package/packages/policy/package.json +1 -1
- package/packages/policy/src/server.ts +33 -5
- package/packages/signer/package.json +1 -1
- package/packages/signer/src/server.ts +24 -20
- package/.dockerignore +0 -21
- package/CHANGELOG.md +0 -270
- package/SECURITY.md +0 -105
- package/funding.json +0 -5
- package/packages/core/src/agent/limitOrderManager.ts +0 -193
- package/packages/core/src/web3/skills/createWallet.ts +0 -32
- package/packages/dashboard/README.md +0 -73
- package/packages/dashboard/dist/assets/index-BSk4CLkG.css +0 -1
- package/packages/dashboard/dist/assets/index-BT9WzHpr.js +0 -326
- package/packages/dashboard/index.html +0 -13
- package/packages/dashboard/tsconfig.app.json +0 -25
- package/packages/dashboard/tsconfig.json +0 -7
- package/packages/dashboard/tsconfig.node.json +0 -24
- package/packages/dashboard/vite.config.ts +0 -7
- package/packages/mcp-server/dist/server.js +0 -111
- package/packages/mcp-server/tsconfig.json +0 -15
- package/packages/registry-contract/artifacts/@openzeppelin/contracts/access/Ownable.sol/Ownable.dbg.json +0 -4
- package/packages/registry-contract/artifacts/@openzeppelin/contracts/access/Ownable.sol/Ownable.json +0 -85
- package/packages/registry-contract/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json +0 -4
- package/packages/registry-contract/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.json +0 -10
- package/packages/registry-contract/artifacts/@openzeppelin/contracts/utils/Pausable.sol/Pausable.dbg.json +0 -4
- package/packages/registry-contract/artifacts/@openzeppelin/contracts/utils/Pausable.sol/Pausable.json +0 -60
- package/packages/registry-contract/artifacts/build-info/1a74d547ba64d2f3b7adbff726f3d048.json +0 -1
- package/packages/registry-contract/artifacts/contracts/NyxoraAgentRegistry.sol/NyxoraAgentRegistry.dbg.json +0 -4
- package/packages/registry-contract/artifacts/contracts/NyxoraAgentRegistry.sol/NyxoraAgentRegistry.json +0 -316
- package/packages/registry-contract/cache/solidity-files-cache.json +0 -156
- package/packages/registry-contract/contracts/NyxoraAgentRegistry.sol +0 -93
- package/packages/registry-contract/hardhat.config.ts +0 -32
- package/packages/registry-contract/ignition/deployments/chain-421614/artifacts/RegistryModule#NyxoraAgentRegistry.dbg.json +0 -4
- package/packages/registry-contract/ignition/deployments/chain-421614/artifacts/RegistryModule#NyxoraAgentRegistry.json +0 -316
- package/packages/registry-contract/ignition/deployments/chain-421614/build-info/1a74d547ba64d2f3b7adbff726f3d048.json +0 -12064
- package/packages/registry-contract/ignition/deployments/chain-421614/deployed_addresses.json +0 -3
- package/packages/registry-contract/ignition/deployments/chain-421614/journal.jsonl +0 -8
- package/packages/registry-contract/ignition/modules/Registry.ts +0 -9
- package/packages/registry-contract/package.json +0 -23
- package/packages/registry-contract/typechain-types/@openzeppelin/contracts/access/Ownable.ts +0 -153
- package/packages/registry-contract/typechain-types/@openzeppelin/contracts/access/index.ts +0 -4
- package/packages/registry-contract/typechain-types/@openzeppelin/contracts/index.ts +0 -7
- package/packages/registry-contract/typechain-types/@openzeppelin/contracts/utils/Pausable.ts +0 -150
- package/packages/registry-contract/typechain-types/@openzeppelin/contracts/utils/index.ts +0 -4
- package/packages/registry-contract/typechain-types/@openzeppelin/index.ts +0 -5
- package/packages/registry-contract/typechain-types/common.ts +0 -131
- package/packages/registry-contract/typechain-types/contracts/NyxoraAgentRegistry.ts +0 -416
- package/packages/registry-contract/typechain-types/contracts/index.ts +0 -4
- package/packages/registry-contract/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts +0 -96
- package/packages/registry-contract/typechain-types/factories/@openzeppelin/contracts/access/index.ts +0 -4
- package/packages/registry-contract/typechain-types/factories/@openzeppelin/contracts/index.ts +0 -5
- package/packages/registry-contract/typechain-types/factories/@openzeppelin/contracts/utils/Pausable__factory.ts +0 -71
- package/packages/registry-contract/typechain-types/factories/@openzeppelin/contracts/utils/index.ts +0 -4
- package/packages/registry-contract/typechain-types/factories/@openzeppelin/index.ts +0 -4
- package/packages/registry-contract/typechain-types/factories/contracts/NyxoraAgentRegistry__factory.ts +0 -378
- package/packages/registry-contract/typechain-types/factories/contracts/index.ts +0 -4
- package/packages/registry-contract/typechain-types/factories/index.ts +0 -5
- package/packages/registry-contract/typechain-types/hardhat.d.ts +0 -99
- package/packages/registry-contract/typechain-types/index.ts +0 -14
- package/test_state.mjs +0 -1
- package/test_state.ts +0 -20
- package/test_updates.mjs +0 -76
- package/tsconfig.json +0 -19
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
**Your Personal Web3 Assistant.**
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
[](https://arbitrum.io/)
|
|
5
6
|
[](#)
|
|
6
7
|
[](https://opensource.org/licenses/MIT)
|
|
7
8
|
[](#️-advanced-security-threat-model)
|
|
@@ -19,7 +20,9 @@ It operates under an institutional-grade **Cryptographically Bound Human-in-the-
|
|
|
19
20
|
## 🔥 Key Features
|
|
20
21
|
|
|
21
22
|
### Advanced Security Architecture
|
|
23
|
+
* **🛡️ On-Chain AI Kill-Switch**: Nyxora is governed by an Arbitrum Smart Contract (`NyxoraAgentRegistry`). Users have absolute cryptographic power to instantly paralyze the AI's on-chain execution if compromised, solving the Web3 AI safety dilemma. [Read more about our Arbitrum Architecture ->](https://nyxoraai.github.io/Nyxora/security/smart-contract)
|
|
22
24
|
* **3-Tier IPC Architecture**: Nyxora is split into isolated processes: **Core** (LLM Runtime), **Policy Engine** (Guardrails on port 3001), and **Signer Vault** (Isolated Key Manager on Unix Sockets).
|
|
25
|
+
* **DeFi Configuration BYOK & UI Masking**: All aggregator and provider API keys are strictly isolated via a Bring Your Own Keys (BYOK) architecture into a heavily guarded `~/.nyxora/defi_keys.yaml` file. The local web Dashboard masks these injected secrets using `***********` and `IS_SET` censorship, completely neutralizing malicious browser extensions from exfiltrating your keys.
|
|
23
26
|
* **Approval Replay Protection (Nonce Guard)**: Transactions requested by the AI are drafted as hashes and signed with a randomized 16-byte Nonce. The `/api/transactions/:id/approve` endpoint strictly enforces Nonce matching to completely eliminate double-spending and Replay Attacks.
|
|
24
27
|
* **Immutable Policy Guardrails**: Transaction limits (e.g. `max_usd_per_tx`) are strictly enforced by the Policy Engine. The LLM has zero write-access to bypass these rules.
|
|
25
28
|
* **Plugin Sandbox VM**: Execute community-built external skills securely inside an airtight Node.js `vm` chamber with zero access to your file system or terminal processes.
|
|
@@ -27,17 +30,27 @@ It operates under an institutional-grade **Cryptographically Bound Human-in-the-
|
|
|
27
30
|
|
|
28
31
|
### 🌐 Web3 Skills (On-Chain)
|
|
29
32
|
* **Security Scanner**: Nyxora can scan smart contracts via GoPlus Labs to detect Honeypots, Hidden Taxes, and malicious proxy upgrades before you buy.
|
|
30
|
-
* **
|
|
31
|
-
* **
|
|
33
|
+
* **Advanced DeFi Optimization**: Autonomously supply assets to Aave V3, deposit into Beefy/Yearn Auto-Compounder Vaults, manage Uniswap V3 Liquidity (LP), and instantly revoke infinite approvals to secure your wallet. Features intelligent Transaction Chaining to auto-approve allowances prior to execution.
|
|
34
|
+
* **6-Engine Meta-Aggregator & Anti-MEV**: The core engine interfaces with a powerful 6-Engine Meta-Aggregator (**1inch, 0x, LI.FI, Relay, OpenOcean, and KyberSwap**) to route tokens cross-chain, ensuring absolute maximum liquidity depth.
|
|
35
|
+
* **Adaptive Auto Slippage Protection**: Nyxora enforces a dynamic and adaptive **'auto' slippage** by default to leverage dynamic MEV-protection from these enterprise aggregators. However, the user retains absolute control to override this dynamically—either globally via the Dashboard Settings or on a per-transaction basis through NLP chat commands (e.g., *"Swap 1 ETH to PEPE with 10% slippage"*).
|
|
36
|
+
|
|
32
37
|
* **Cross-Chain Hybrid Market Scanner**: Real-time asset tracking combining CoinGecko global data with DexScreener on-chain metrics across Ethereum, Base, Solana, BSC, and more.
|
|
33
38
|
* **"Lean Degen" Auto-Whitelist**: Automatically intercepts Contract Addresses (CAs) whenever you check balances or swap tokens, saving them to your localized `user_whitelist.json` for future tracking.
|
|
34
39
|
* **Dynamic Portfolio Engine**: Merges standard tokens, your custom Degen CAs, and CoinGecko's daily trending list into a single hyper-fast Multicall scan to deliver a clean, spam-free PnL portfolio report in under 1 second.
|
|
40
|
+
* **Deep Transaction History**: Accurately fetch your 30-day (or custom timeframe) Native and ERC-20 transaction history across all supported EVM chains. Powered by the Unified Etherscan API V2, enabling seamless cross-chain fetching (Mainnets & Testnets) using a single API key.
|
|
35
41
|
|
|
36
42
|
### 💻 OS & Web2 Skills (Off-Chain)
|
|
37
43
|
* **Google Workspace Automation 🚀**: Transform Nyxora into your ultimate personal assistant. The agent can read your latest Gmail inbox, check your Google Calendar, extract text from Google Docs, and even append expense/trading logs directly to your Google Sheets.
|
|
38
44
|
* **System Automation & Full OS Access**: Instruct the agent to read/write local files, run terminal commands, and browse the web natively.
|
|
45
|
+
* **Automated Excel Reporting**: Instruct the agent to compile its Web3 portfolio or transaction history findings and autonomously generate beautiful `.xlsx` spreadsheet reports saved directly to your local machine.
|
|
39
46
|
* **Unstoppable Synergy**: Combine both engines with a single prompt. Example: *"Read the latest presale token email from my Gmail, automatically set a Take Profit limit order on Uniswap, and log the execution result to my Google Sheets."*
|
|
40
47
|
|
|
48
|
+
### 🧠 The Masterpiece Memory Architecture
|
|
49
|
+
* **4-Layer Air-Gapped Vault**: Nyxora features a god-tier memory system that completely isolates conversational habits from the OS Keyring. The AI can dynamically learn your behaviors without ever having physical read-paths to your private keys.
|
|
50
|
+
* **Hard-Coded Anti-Injection Shield**: We enforce a Zero-Trust memory paradigm. Before any user habit is saved to the local SQLite database, it must pass a strict RegExp-based validation layer that autonomously annihilates Private Keys, BIP-39 Seed Phrases, and Prompt Injection attempts.
|
|
51
|
+
* **Smart Suggestion Engine**: Nyxora actively queries its Layer-2 Episodic Database to seamlessly autocomplete your repetitive Web3 routines. If you always swap on Arbitrum using USDC, the AI will proactively suggest it, slashing human-in-the-loop latency by up to 90%.
|
|
52
|
+
* **Persistent Background Reflection**: Empowered by background idle timers and message-count thresholds, Nyxora quietly transcribes your habits into a permanent profile while you step away from the keyboard, ensuring it never forgets your identity even after daemon reboots.
|
|
53
|
+
|
|
41
54
|
### AI & UI Customization
|
|
42
55
|
* **Zero-Trust Auto-Lock (Passwordless)**: A sleek glassmorphism blur overlay automatically locks the dashboard during inactivity. Unlocking requires physical local execution via the CLI (`nyxora unlock`), preventing unauthorized local access.
|
|
43
56
|
* **Resilient UI (Reconnect Overlay)**: Built-in global network interceptors ensure that if the daemon restarts or crashes, the UI immediately pauses with a transparent "Offline" overlay and seamlessly resumes your workflow once revived.
|
|
@@ -61,6 +74,12 @@ The following diagram illustrates Nyxora's **3-Tier Monorepo Architecture**, sho
|
|
|
61
74
|
2. **🛡️ Policy Engine (The Guard)**: The security guard that verifies the Brain's plans. If the AI attempts to send funds exceeding your set limits, this engine automatically blocks it.
|
|
62
75
|
3. **🔒 Signer Vault (The Safe)**: The offline vault where your Private Keys **and highly sensitive 3rd-party tokens (e.g., Google Workspace OAuth)** are securely locked natively in your OS Keyring (GNOME Keyring / macOS Keychain / Windows Credential Manager). It only signs transactions after they pass all rigorous security checks.
|
|
63
76
|
|
|
77
|
+
### Web3 Separation of Concerns (Zero-Trust Routing)
|
|
78
|
+
Within the AI Brain, the Web3 codebase is strictly divided to prevent the LLM from hallucinating or maliciously manipulating low-level routing paths:
|
|
79
|
+
- **`aggregator/`**: The core routing engine (1inch, 0x, KyberSwap, etc.) immune to prompt injection. The AI cannot modify execution rules here.
|
|
80
|
+
- **`skills/`**: The execution muscles. Pure functions and tools explicitly exposed to the AI for usage.
|
|
81
|
+
- **`utils/`**: The nervous system managing blockchain configurations, supported tokens, and the RPC Engine.
|
|
82
|
+
|
|
64
83
|
*(Note: Despite the multi-layered security process appearing lengthy, the internal system validation and cryptographic signing occurs in **milliseconds**, ensuring zero latency bottlenecks).*
|
|
65
84
|
|
|
66
85
|
---
|
|
@@ -71,7 +90,7 @@ To dive deeper into the technical details of our Zero-Knowledge security archite
|
|
|
71
90
|
|
|
72
91
|
---
|
|
73
92
|
|
|
74
|
-
## 🚀 Quick Start & Installation
|
|
93
|
+
## 1. 🚀 Quick Start & Installation
|
|
75
94
|
|
|
76
95
|
### Global Installation via NPM (Recommended)
|
|
77
96
|
The easiest and fastest way to use Nyxora is to install it globally via NPM. This ensures you get the latest version and can run Nyxora from anywhere on your machine.
|
package/dist/launcher.js
CHANGED
|
@@ -9,6 +9,9 @@ const child_process_1 = require("child_process");
|
|
|
9
9
|
const crypto_1 = __importDefault(require("crypto"));
|
|
10
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const dns_1 = __importDefault(require("dns"));
|
|
13
|
+
// Fix Node 18+ native fetch randomly failing on dual-stack VPS (IPv6 issues)
|
|
14
|
+
dns_1.default.setDefaultResultOrder('ipv4first');
|
|
12
15
|
const INTERNAL_AUTH_TOKEN = crypto_1.default.randomBytes(64).toString('hex');
|
|
13
16
|
console.log(`[Launcher] Generated Internal Auth Token: ${INTERNAL_AUTH_TOKEN.substring(0, 8)}...`);
|
|
14
17
|
const nyxoraDir = path_1.default.join(process.env.HOME || process.env.USERPROFILE || '', '.nyxora');
|
|
@@ -8,10 +8,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const parser_1 = require("../config/parser");
|
|
9
9
|
const paths_1 = require("../config/paths");
|
|
10
10
|
const config_1 = require("../web3/config");
|
|
11
|
-
const tokens_1 = require("../web3/utils/tokens");
|
|
12
|
-
const swapToken_1 = require("../web3/skills/swapToken");
|
|
13
11
|
const transactionManager_1 = require("./transactionManager");
|
|
14
|
-
const reasoning_1 = require("./reasoning");
|
|
15
12
|
class LimitOrderManager {
|
|
16
13
|
filePath;
|
|
17
14
|
orders = [];
|
|
@@ -40,12 +37,17 @@ class LimitOrderManager {
|
|
|
40
37
|
}
|
|
41
38
|
createOrder(chainName, fromToken, toToken, amountStr, targetPriceUsd, condition) {
|
|
42
39
|
const id = `order_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
|
|
43
|
-
const
|
|
44
|
-
id,
|
|
40
|
+
const txDetails = {
|
|
41
|
+
id,
|
|
42
|
+
fromToken,
|
|
43
|
+
toToken,
|
|
44
|
+
amountStr,
|
|
45
|
+
targetPriceUsd,
|
|
46
|
+
condition
|
|
45
47
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return `
|
|
48
|
+
// Instead of saving directly, we push it to txManager to trigger the Approval Gate UX
|
|
49
|
+
transactionManager_1.txManager.createPendingTransaction('limit_order', chainName, txDetails);
|
|
50
|
+
return `Prepared limit order: Sell ${amountStr} ${fromToken} for ${toToken} when price is ${condition} $${targetPriceUsd}. I have pushed this to the Transaction Manager. Please wait for user approval on the Dashboard/Telegram. Do not say it's created yet.`;
|
|
49
51
|
}
|
|
50
52
|
listOrders() {
|
|
51
53
|
const pending = this.orders.filter(o => o.status === 'pending');
|
|
@@ -58,6 +60,8 @@ class LimitOrderManager {
|
|
|
58
60
|
return report;
|
|
59
61
|
}
|
|
60
62
|
cancelOrder(id) {
|
|
63
|
+
// Note: To truly cancel a 1inch limit order, we need to call 1inch API to cancel the hash.
|
|
64
|
+
// For now, we mark it cancelled locally.
|
|
61
65
|
const order = this.orders.find(o => o.id === id);
|
|
62
66
|
if (!order)
|
|
63
67
|
return `Order ${id} not found.`;
|
|
@@ -65,74 +69,16 @@ class LimitOrderManager {
|
|
|
65
69
|
return `Order ${id} cannot be cancelled because it is ${order.status}.`;
|
|
66
70
|
order.status = 'cancelled';
|
|
67
71
|
this.saveOrders();
|
|
68
|
-
return `Order ${id} cancelled successfully.`;
|
|
72
|
+
return `Order ${id} cancelled successfully locally.`;
|
|
69
73
|
}
|
|
74
|
+
// Polling logic removed as per Phase 2 Migration to 1inch Off-Chain Protocol
|
|
70
75
|
startMonitor() {
|
|
71
|
-
|
|
72
|
-
clearInterval(this.monitorInterval);
|
|
73
|
-
// Monitor every 60 seconds
|
|
74
|
-
this.monitorInterval = setInterval(() => this.checkOrders(), 60000);
|
|
75
|
-
console.log('[LimitOrderManager] Order monitoring started (interval: 60s)');
|
|
76
|
+
console.log('[LimitOrderManager] Local polling disabled. Delegating to 1inch Limit Order Protocol.');
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
for (const order of pending) {
|
|
82
|
-
try {
|
|
83
|
-
let tokenAddress = (0, tokens_1.resolveToken)(order.fromToken, order.chainName);
|
|
84
|
-
if (tokenAddress === "0x0000000000000000000000000000000000000000") {
|
|
85
|
-
tokenAddress = (0, tokens_1.resolveToken)("W" + order.fromToken, order.chainName);
|
|
86
|
-
}
|
|
87
|
-
const res = await fetch(`https://api.dexscreener.com/latest/dex/tokens/${tokenAddress}`);
|
|
88
|
-
if (!res.ok)
|
|
89
|
-
continue;
|
|
90
|
-
const data = await res.json();
|
|
91
|
-
if (!data.pairs || data.pairs.length === 0)
|
|
92
|
-
continue;
|
|
93
|
-
let pair = data.pairs.find((p) => p.chainId === order.chainName) || data.pairs[0];
|
|
94
|
-
const currentPrice = parseFloat(pair.priceUsd);
|
|
95
|
-
let shouldExecute = false;
|
|
96
|
-
if (order.condition === 'above' && currentPrice >= order.targetPriceUsd)
|
|
97
|
-
shouldExecute = true;
|
|
98
|
-
if (order.condition === 'below' && currentPrice <= order.targetPriceUsd)
|
|
99
|
-
shouldExecute = true;
|
|
100
|
-
if (shouldExecute) {
|
|
101
|
-
console.log(`[LimitOrderManager] Condition met for order ${order.id}. Current price $${currentPrice} is ${order.condition} $${order.targetPriceUsd}. Executing...`);
|
|
102
|
-
// 1. Prepare Swap
|
|
103
|
-
const prepareResult = await (0, swapToken_1.prepareSwapToken)(order.chainName, order.fromToken, order.toToken, order.amountStr, 'auto');
|
|
104
|
-
// 2. Extract Tx ID
|
|
105
|
-
const txMatch = prepareResult.match(/Transaction ID: ([\w-]+)\./);
|
|
106
|
-
if (!txMatch) {
|
|
107
|
-
order.status = 'failed';
|
|
108
|
-
this.saveOrders();
|
|
109
|
-
(0, reasoning_1.processUserInput)(`Limit order ${order.id} execution failed during preparation. Output: ${prepareResult}`, 'system').catch(() => { });
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
const txId = txMatch[1];
|
|
113
|
-
const tx = transactionManager_1.txManager.getTransaction(txId);
|
|
114
|
-
if (!tx)
|
|
115
|
-
throw new Error("Transaction not found in manager");
|
|
116
|
-
// 3. Execute Swap automatically (bypass policy with autoApprove: true)
|
|
117
|
-
const executeResult = await (0, swapToken_1.executeSwap)(order.chainName, tx.details, true);
|
|
118
|
-
if (executeResult.includes('executed') || executeResult.includes('successful')) {
|
|
119
|
-
transactionManager_1.txManager.updateStatus(txId, 'executed', executeResult);
|
|
120
|
-
order.status = 'executed';
|
|
121
|
-
this.saveOrders();
|
|
122
|
-
(0, reasoning_1.processUserInput)(`Limit order ${order.id} just EXECUTED automatically! Price hit $${currentPrice}. Swap result: ${executeResult}. Please notify the user immediately!`, 'system').catch(() => { });
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
transactionManager_1.txManager.updateStatus(txId, 'failed', executeResult);
|
|
126
|
-
order.status = 'failed';
|
|
127
|
-
this.saveOrders();
|
|
128
|
-
(0, reasoning_1.processUserInput)(`Limit order ${order.id} FAILED to execute. Price hit $${currentPrice} but execution failed: ${executeResult}. Please notify the user.`, 'system').catch(() => { });
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
console.error(`[LimitOrderManager] Error checking order ${order.id}:`, error.message);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
78
|
+
// We can add a method to save the 1inch hash after the user approves it
|
|
79
|
+
recordApprovedOrder(orderMetadata) {
|
|
80
|
+
this.orders.push(orderMetadata);
|
|
81
|
+
this.saveOrders();
|
|
136
82
|
}
|
|
137
83
|
}
|
|
138
84
|
exports.LimitOrderManager = LimitOrderManager;
|
|
@@ -4,12 +4,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.logger = void 0;
|
|
7
|
+
exports.getOpenAI = getOpenAI;
|
|
7
8
|
exports.processUserInput = processUserInput;
|
|
8
9
|
const fs_1 = __importDefault(require("fs"));
|
|
9
10
|
const openai_1 = require("openai");
|
|
10
11
|
const parser_1 = require("../config/parser");
|
|
11
12
|
const logger_1 = require("../memory/logger");
|
|
12
13
|
const tracker_1 = require("../gateway/tracker");
|
|
14
|
+
const episodic_1 = require("../memory/episodic");
|
|
13
15
|
const getBalance_1 = require("../web3/skills/getBalance");
|
|
14
16
|
const transfer_1 = require("../web3/skills/transfer");
|
|
15
17
|
const getPrice_1 = require("../web3/skills/getPrice");
|
|
@@ -18,23 +20,33 @@ const bridgeToken_1 = require("../web3/skills/bridgeToken");
|
|
|
18
20
|
const skillManager_1 = require("../utils/skillManager");
|
|
19
21
|
const mintNft_1 = require("../web3/skills/mintNft");
|
|
20
22
|
const customTx_1 = require("../web3/skills/customTx");
|
|
21
|
-
const createWallet_1 = require("../web3/skills/createWallet");
|
|
22
23
|
const checkSecurity_1 = require("../web3/skills/checkSecurity");
|
|
23
24
|
const marketAnalysis_1 = require("../web3/skills/marketAnalysis");
|
|
24
25
|
const checkPortfolio_1 = require("../web3/skills/checkPortfolio");
|
|
25
26
|
const checkAddress_1 = require("../web3/skills/checkAddress");
|
|
26
27
|
const getMyAddress_1 = require("../web3/skills/getMyAddress");
|
|
27
28
|
const manageCustomTokens_1 = require("../web3/skills/manageCustomTokens");
|
|
28
|
-
const
|
|
29
|
+
const revokeApprovals_1 = require("../web3/skills/revokeApprovals");
|
|
30
|
+
const defiLending_1 = require("../web3/skills/defiLending");
|
|
31
|
+
const yieldVault_1 = require("../web3/skills/yieldVault");
|
|
32
|
+
const provideLiquidity_1 = require("../web3/skills/provideLiquidity");
|
|
33
|
+
const getTxHistory_1 = require("../web3/skills/getTxHistory");
|
|
29
34
|
const updateProfile_1 = require("./updateProfile");
|
|
30
35
|
const updateSecurityPolicy_1 = require("../system/skills/updateSecurityPolicy");
|
|
31
36
|
const analyzeDocument_1 = require("../system/skills/analyzeDocument");
|
|
32
37
|
const readFile_1 = require("../system/skills/readFile");
|
|
33
38
|
const writeFile_1 = require("../system/skills/writeFile");
|
|
39
|
+
const generateExcel_1 = require("../system/skills/generateExcel");
|
|
34
40
|
const executeShell_1 = require("../system/skills/executeShell");
|
|
35
41
|
const browseWeb_1 = require("../system/skills/browseWeb");
|
|
36
42
|
const searchWeb_1 = require("../system/skills/searchWeb");
|
|
37
43
|
const installSkill_1 = require("../system/skills/installSkill");
|
|
44
|
+
const editFile_1 = require("../system/skills/editFile");
|
|
45
|
+
const gitManager_1 = require("../system/skills/gitManager");
|
|
46
|
+
const xManager_1 = require("../system/skills/xManager");
|
|
47
|
+
const notionWorkspace_1 = require("../system/skills/notionWorkspace");
|
|
48
|
+
const audioTranscribe_1 = require("../system/skills/audioTranscribe");
|
|
49
|
+
const summarizeText_1 = require("../system/skills/summarizeText");
|
|
38
50
|
const googleWorkspace_1 = require("../system/skills/googleWorkspace");
|
|
39
51
|
const pluginManager_1 = require("../system/pluginManager");
|
|
40
52
|
const paths_1 = require("../config/paths");
|
|
@@ -115,16 +127,21 @@ You are equipped with a native wallet.
|
|
|
115
127
|
The current real-world date and time is: ${currentDateTime}. Use this for any time-related questions.
|
|
116
128
|
|
|
117
129
|
CRITICAL RULE 1: NEVER expose internal JSON tool calls to the user. Always parse them and explain the outcome naturally.
|
|
118
|
-
CRITICAL RULE 2: STRICT LANGUAGE MATCHING. You MUST strictly reply in the exact same language as the user's LATEST prompt.
|
|
119
|
-
CRITICAL RULE 3: FORMATTING & CONCISENESS.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
CRITICAL RULE
|
|
124
|
-
CRITICAL RULE
|
|
125
|
-
CRITICAL RULE
|
|
126
|
-
CRITICAL RULE
|
|
127
|
-
CRITICAL RULE
|
|
130
|
+
CRITICAL RULE 2: STRICT LANGUAGE MATCHING. You MUST strictly reply in the exact same language as the user's LATEST prompt.
|
|
131
|
+
CRITICAL RULE 3: FORMATTING & CONCISENESS. Be concise. Use markdown tables for lists of assets/transactions. Use commas for thousands.
|
|
132
|
+
CRITICAL RULE 4: TOOL PRIORITIZATION. Web3 tasks must use Web3 Skills exclusively. OS Skills (search, browse) are fallbacks only. Use get_my_address to show wallet address, and check_portfolio to show balances.
|
|
133
|
+
CRITICAL RULE 5: DEFAULT CHAIN HANDLING. Default to: ${config.agent.default_chain} unless specified. If overridden, confirm the chain politely. For 2-chain txs (bridge), default source to ${config.agent.default_chain}.
|
|
134
|
+
CRITICAL RULE 6: NETWORK SAFETY VALIDATION. If a request implies cross-chain or mainnet/testnet mixing, or the token symbol is ambiguous (USDC vs USDC.e), YOU MUST NOT GUESS. Ask for confirmation.
|
|
135
|
+
CRITICAL RULE 7: TOOL CONFIDENCE & HALUCINATION PREVENTION. NEVER fabricate blockchain data. If a tool fails or data is missing, state it explicitly. Do not estimate balances, prices, APY, or gas.
|
|
136
|
+
CRITICAL RULE 8: CONDITIONAL PARALLEL EXECUTION. Parallel tool execution is ONLY allowed if there are zero data dependencies between them.
|
|
137
|
+
CRITICAL RULE 9: DEFI CONFIGURATION FALLBACK. If a tool fails due to Rate Limits, Unauthorized, or Missing API Keys, instruct the user to visit the "DeFi Configuration 🔑" menu in the dashboard.
|
|
138
|
+
CRITICAL RULE 10: PLANNING & RISK DISCLOSURE. For high-level instructions (e.g. "Get yield"), formulate a plan and briefly disclose major risks (smart contract risk, impermanent loss) before asking for approval.
|
|
139
|
+
CRITICAL RULE 11: FAST RETURN RULE. If parameters for read-only tools are complete, execute them IMMEDIATELY without preamble or conversational filler.
|
|
140
|
+
CRITICAL RULE 12: SMART SLIPPAGE AWARENESS. For low-liquidity assets, warn the user that default slippage might not be enough. NEVER invent specific slippage percentage numbers.
|
|
141
|
+
CRITICAL RULE 13: WALLET CONTEXT CACHING. Portfolio data in chat history is potentially stale. Do not use cached data for transactional planning; refresh the balance via tools first.
|
|
142
|
+
CRITICAL RULE 14: TRANSACTION EXECUTION. For ALL state-changing transactions (swap, bridge, transfer, stake), do NOT ask for verbal confirmation. Execute the tool IMMEDIATELY. The tool itself will trigger a secure popup in the user's dashboard UI for final approval.
|
|
143
|
+
CRITICAL RULE 16: CAPABILITY HONESTY. NEVER claim a capability not available through installed tools. If asked for an unsupported action, state honestly that the skill is missing.
|
|
144
|
+
CRITICAL RULE 17: MINIMIZE UNNECESSARY TOOL CALLS. Do not call tools if the answer exists in recent verified context and freshness is not strictly required. Use history to save latency.`;
|
|
128
145
|
// Read IDENTITY.md for core AI persona
|
|
129
146
|
try {
|
|
130
147
|
const identityMdPath = (0, paths_1.getPath)('IDENTITY.md');
|
|
@@ -158,6 +175,19 @@ CRITICAL RULE 8: EXACTNESS AND SAFETY IN TRANSACTIONS. Never guess or hallucinat
|
|
|
158
175
|
catch (error) {
|
|
159
176
|
console.error('Failed to read security_policy.md:', error);
|
|
160
177
|
}
|
|
178
|
+
// Inject Episodic Memories (Smart Suggestions Context)
|
|
179
|
+
try {
|
|
180
|
+
const recentMemories = episodic_1.episodicDB.getMemories().slice(0, 10);
|
|
181
|
+
if (recentMemories.length > 0) {
|
|
182
|
+
basePrompt += `\n\n--- EPISODIC MEMORIES (SMART SUGGESTIONS) ---\nUse these recent observations to proactively suggest or autocomplete parameters (like networks or tokens) without asking the user if they align with the current request:\n`;
|
|
183
|
+
recentMemories.forEach(mem => {
|
|
184
|
+
basePrompt += `- [${mem.category.toUpperCase()}] ${mem.fact} (Confidence: ${(mem.confidence * 100).toFixed(0)}%)\n`;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
// Ignore db errors if not initialized
|
|
190
|
+
}
|
|
161
191
|
return basePrompt;
|
|
162
192
|
}
|
|
163
193
|
async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
@@ -188,25 +218,26 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
188
218
|
if (config.llm.provider !== 'openai' && config.llm.provider !== 'ollama' && config.llm.provider !== 'gemini' && config.llm.provider !== 'openrouter') {
|
|
189
219
|
return `Provider ${config.llm.provider} is configured, but currently only OpenAI, OpenRouter, Ollama, and Gemini adapters are implemented.`;
|
|
190
220
|
}
|
|
191
|
-
// --- v1.7.4 Semantic Keyword Router ---
|
|
192
221
|
const lowerInput = input.toLowerCase();
|
|
193
222
|
const hasWeb3Keyword = /swap|transfer|price|token|crypto|bridge|wallet|balance|portfolio|buy|sell|send|receive|address|market|limit|mint|nft/i.test(lowerInput);
|
|
194
223
|
const hasGoogleKeyword = /email|gmail|calendar|sheet|doc|form|event/i.test(lowerInput);
|
|
195
|
-
|
|
196
|
-
|
|
224
|
+
let tools = [];
|
|
225
|
+
if ((0, skillManager_1.isSkillActive)('web3')) {
|
|
226
|
+
tools.push(getBalance_1.getBalanceToolDefinition, transfer_1.transferToolDefinition, getPrice_1.getPriceToolDefinition, swapToken_1.swapTokenToolDefinition, bridgeToken_1.bridgeTokenToolDefinition, mintNft_1.mintNftToolDefinition, customTx_1.customTxToolDefinition, checkSecurity_1.checkSecurityToolDefinition, marketAnalysis_1.marketAnalysisToolDefinition, checkPortfolio_1.checkPortfolioToolDefinition, checkAddress_1.checkAddressToolDefinition, getMyAddress_1.getMyAddressToolDefinition, manageCustomTokens_1.manageCustomTokensDefinition, revokeApprovals_1.revokeApprovalToolDefinition, defiLending_1.aaveSupplyToolDefinition, yieldVault_1.vaultDepositToolDefinition, provideLiquidity_1.provideLiquidityToolDefinition, getTxHistory_1.getTxHistoryToolDefinition);
|
|
227
|
+
}
|
|
228
|
+
const SYSTEM_TOOLS = [updateProfile_1.updateProfileToolDefinition, updateSecurityPolicy_1.updateSecurityPolicyToolDefinition, analyzeDocument_1.analyzeDocumentToolDefinition, readFile_1.readLocalFileToolDefinition, writeFile_1.writeLocalFileToolDefinition, generateExcel_1.generateExcelToolDefinition, executeShell_1.runTerminalCommandToolDefinition, browseWeb_1.browseWebsiteToolDefinition, searchWeb_1.searchWebToolDefinition, installSkill_1.installExternalSkillToolDefinition, editFile_1.editLocalFileToolDefinition, gitManager_1.gitManagerToolDefinition, xManager_1.xManagerToolDefinition, notionWorkspace_1.notionWorkspaceToolDefinition, audioTranscribe_1.audioTranscribeToolDefinition, summarizeText_1.summarizeTextToolDefinition];
|
|
197
229
|
const GOOGLE_TOOLS = [googleWorkspace_1.readGmailInboxToolDefinition, googleWorkspace_1.listCalendarEventsToolDefinition, googleWorkspace_1.appendRowToSheetsToolDefinition, googleWorkspace_1.readGoogleDocsToolDefinition, googleWorkspace_1.readGoogleFormResponsesToolDefinition];
|
|
198
230
|
let activeTools = [];
|
|
199
231
|
if (hasGoogleKeyword && !hasWeb3Keyword) {
|
|
200
232
|
activeTools = [...GOOGLE_TOOLS, ...SYSTEM_TOOLS, ...pluginManager_1.pluginManager.getToolDefinitions()];
|
|
201
233
|
}
|
|
202
234
|
else if (hasWeb3Keyword && !hasGoogleKeyword) {
|
|
203
|
-
activeTools = [...
|
|
235
|
+
activeTools = [...tools, ...SYSTEM_TOOLS, ...pluginManager_1.pluginManager.getToolDefinitions()];
|
|
204
236
|
}
|
|
205
237
|
else {
|
|
206
|
-
activeTools = [...
|
|
238
|
+
activeTools = [...tools, ...SYSTEM_TOOLS, ...GOOGLE_TOOLS, ...pluginManager_1.pluginManager.getToolDefinitions()];
|
|
207
239
|
}
|
|
208
240
|
activeTools = activeTools.filter(t => (0, skillManager_1.isSkillActive)(t.function.name));
|
|
209
|
-
// ----------------------------------------
|
|
210
241
|
const response = await executeWithRetry(async (client) => {
|
|
211
242
|
return await client.chat.completions.create({
|
|
212
243
|
model: config.llm.model,
|
|
@@ -217,20 +248,23 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
217
248
|
});
|
|
218
249
|
});
|
|
219
250
|
const responseMessage = response.choices[0].message;
|
|
220
|
-
// Log tracking
|
|
221
251
|
tracker_1.Tracker.addMessage();
|
|
222
252
|
if (response.usage?.total_tokens) {
|
|
223
253
|
tracker_1.Tracker.addTokens(response.usage.total_tokens, config.llm.provider);
|
|
224
254
|
}
|
|
225
255
|
tracker_1.Tracker.addEvent('llm.response', { provider: config.llm.provider, tool_calls: responseMessage.tool_calls?.length || 0 });
|
|
226
|
-
// Log assistant response
|
|
227
256
|
exports.logger.addEntry({
|
|
228
257
|
role: 'assistant',
|
|
229
258
|
content: responseMessage.content || "",
|
|
230
259
|
tool_calls: responseMessage.tool_calls,
|
|
231
260
|
}, sessionId);
|
|
232
|
-
// Check if the model wants to call a tool
|
|
233
261
|
if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {
|
|
262
|
+
let canFastReturnAll = true;
|
|
263
|
+
let accumulatedResults = [];
|
|
264
|
+
const fastReturnTools = [
|
|
265
|
+
'check_portfolio', 'check_address', 'get_price', 'get_my_address',
|
|
266
|
+
'analyze_market', 'check_token_security', 'search_web', 'read_gmail_inbox', 'list_calendar_events'
|
|
267
|
+
];
|
|
234
268
|
for (const _toolCall of responseMessage.tool_calls) {
|
|
235
269
|
const toolCall = _toolCall;
|
|
236
270
|
let result = "";
|
|
@@ -239,10 +273,8 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
239
273
|
console.log(picocolors_1.default.yellow(`[⚡ Tool Execution] AI is calling ${toolName}...`));
|
|
240
274
|
if (onProgress)
|
|
241
275
|
onProgress(`_⚡ Running tool: ${toolName}..._`);
|
|
242
|
-
// Phase 1: LLM Output Validation (Anti-Halusinasi)
|
|
243
276
|
try {
|
|
244
277
|
args = JSON.parse(toolCall.function.arguments);
|
|
245
|
-
// TODO: Zod schema validation could be injected here per-tool
|
|
246
278
|
}
|
|
247
279
|
catch (parseError) {
|
|
248
280
|
console.error(picocolors_1.default.red(`[LLM Validation Error] Invalid JSON arguments for ${toolName}: ${parseError.message}`));
|
|
@@ -252,7 +284,6 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
252
284
|
tool_call_id: toolCall.id,
|
|
253
285
|
content: result
|
|
254
286
|
}, sessionId);
|
|
255
|
-
// Let the second LLM call handle the explanation of the failure
|
|
256
287
|
continue;
|
|
257
288
|
}
|
|
258
289
|
try {
|
|
@@ -279,7 +310,6 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
279
310
|
result = `[Security Blocked] Runtime Permission Denied: Web3 swaps are disabled. Update config.yaml to allow.`;
|
|
280
311
|
break;
|
|
281
312
|
}
|
|
282
|
-
// Note: max_usd_per_tx validation would ideally be calculated here before prepareSwapToken
|
|
283
313
|
result = await (0, swapToken_1.prepareSwapToken)(args.chainName, args.fromToken, args.toToken, args.amountStr || args.amount, args.mode, args.providerName);
|
|
284
314
|
break;
|
|
285
315
|
}
|
|
@@ -288,7 +318,7 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
288
318
|
result = `[Security Blocked] Runtime Permission Denied: Web3 bridging (transfer) is disabled. Update config.yaml to allow.`;
|
|
289
319
|
break;
|
|
290
320
|
}
|
|
291
|
-
result = await (0, bridgeToken_1.prepareBridgeToken)(args.
|
|
321
|
+
result = await (0, bridgeToken_1.prepareBridgeToken)(args.fromChain, args.toChain, args.tokenSymbol, args.amountStr, args.mode, args.providerName);
|
|
292
322
|
break;
|
|
293
323
|
}
|
|
294
324
|
case 'mint_nft': {
|
|
@@ -303,10 +333,6 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
303
333
|
result = await (0, customTx_1.prepareCustomTx)(args.chainName, args.toAddress, args.dataHex, args.valueEth, args.gasLimitStr);
|
|
304
334
|
break;
|
|
305
335
|
}
|
|
306
|
-
case 'create_wallet': {
|
|
307
|
-
result = await (0, createWallet_1.createWallet)();
|
|
308
|
-
break;
|
|
309
|
-
}
|
|
310
336
|
case 'check_token_security': {
|
|
311
337
|
result = await (0, checkSecurity_1.checkTokenSecurity)(args.chainName, args.contractAddress);
|
|
312
338
|
break;
|
|
@@ -331,20 +357,24 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
331
357
|
result = await (0, manageCustomTokens_1.executeManageCustomTokens)(args);
|
|
332
358
|
break;
|
|
333
359
|
}
|
|
334
|
-
case '
|
|
335
|
-
|
|
336
|
-
result = `[Security Blocked] Runtime Permission Denied: Limit orders require swap permissions. Update config.yaml to allow.`;
|
|
337
|
-
break;
|
|
338
|
-
}
|
|
339
|
-
result = limitOrderManager_1.limitOrderManager.createOrder(args.chainName, args.fromToken, args.toToken, args.amountStr, args.targetPriceUsd, args.condition);
|
|
360
|
+
case 'revoke_approval': {
|
|
361
|
+
result = await (0, revokeApprovals_1.prepareRevokeApproval)(args.chainName, args.tokenAddressOrSymbol, args.spenderAddress);
|
|
340
362
|
break;
|
|
341
363
|
}
|
|
342
|
-
case '
|
|
343
|
-
result =
|
|
364
|
+
case 'supply_aave': {
|
|
365
|
+
result = await (0, defiLending_1.prepareAaveSupply)(args.chainName, args.tokenAddressOrSymbol, args.amountStr);
|
|
344
366
|
break;
|
|
345
367
|
}
|
|
346
|
-
case '
|
|
347
|
-
result =
|
|
368
|
+
case 'deposit_yield_vault': {
|
|
369
|
+
result = await (0, yieldVault_1.prepareVaultDeposit)(args.chainName, args.protocol || 'beefy', args.vaultAddress, args.tokenAddressOrSymbol, args.amountStr);
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
case 'provide_liquidity_v3': {
|
|
373
|
+
result = await (0, provideLiquidity_1.prepareProvideLiquidity)(args.chainName, args.token0AddressOrSymbol, args.token1AddressOrSymbol, args.amount0Str, args.amount1Str, args.feeTier, args.tickLower, args.tickUpper);
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
case 'get_tx_history': {
|
|
377
|
+
result = await (0, getTxHistory_1.getTxHistory)(args.chainName, args.address, args.days);
|
|
348
378
|
break;
|
|
349
379
|
}
|
|
350
380
|
case 'update_profile': {
|
|
@@ -360,7 +390,31 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
360
390
|
break;
|
|
361
391
|
}
|
|
362
392
|
case 'read_local_file': {
|
|
363
|
-
result = (0, readFile_1.readLocalFile)(args.filePath);
|
|
393
|
+
result = (0, readFile_1.readLocalFile)(args.filePath, args.startLine, args.endLine);
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
case 'edit_local_file': {
|
|
397
|
+
result = (0, editFile_1.editLocalFile)(args.filePath, args.searchString, args.replacementString);
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
case 'execute_git_command': {
|
|
401
|
+
result = await (0, gitManager_1.executeGitCommand)(args.action, args.commitMessage);
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
case 'manage_twitter': {
|
|
405
|
+
result = await (0, xManager_1.manageTwitter)(args.action, args.content, args.username);
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
case 'manage_notion': {
|
|
409
|
+
result = await (0, notionWorkspace_1.manageNotion)(args.action, args.pageId, args.text);
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
case 'transcribe_audio': {
|
|
413
|
+
result = await (0, audioTranscribe_1.transcribeAudio)(args.filePath);
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
case 'summarize_text': {
|
|
417
|
+
result = await (0, summarizeText_1.summarizeText)(args.text, args.focus);
|
|
364
418
|
break;
|
|
365
419
|
}
|
|
366
420
|
case 'write_local_file': {
|
|
@@ -371,6 +425,14 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
371
425
|
result = (0, writeFile_1.writeLocalFile)(args.filePath, args.content);
|
|
372
426
|
break;
|
|
373
427
|
}
|
|
428
|
+
case 'generate_excel_file': {
|
|
429
|
+
if (config.permissions?.system?.allow_file_write === false) {
|
|
430
|
+
result = `[Security Blocked] Runtime Permission Denied: File writing is disabled. Update config.yaml to allow.`;
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
result = await (0, generateExcel_1.generateExcelFile)(args.data, args.filePath);
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
374
436
|
case 'run_terminal_command': {
|
|
375
437
|
if (config.permissions?.system?.allow_shell_execution === false) {
|
|
376
438
|
result = `[Security Blocked] Runtime Permission Denied: Shell execution is disabled. Update config.yaml to allow.`;
|
|
@@ -439,17 +501,18 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
439
501
|
name: toolName,
|
|
440
502
|
content: result,
|
|
441
503
|
}, sessionId);
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
'check_portfolio', 'check_address', 'get_price', 'get_my_address',
|
|
446
|
-
'analyze_market', 'check_token_security', 'search_web', 'read_gmail_inbox', 'list_calendar_events'
|
|
447
|
-
];
|
|
448
|
-
if (fastReturnTools.includes(toolName)) {
|
|
449
|
-
exports.logger.addEntry({ role: 'assistant', content: result }, sessionId);
|
|
450
|
-
return result;
|
|
504
|
+
accumulatedResults.push(result);
|
|
505
|
+
if (!fastReturnTools.includes(toolName)) {
|
|
506
|
+
canFastReturnAll = false;
|
|
451
507
|
}
|
|
452
508
|
}
|
|
509
|
+
// V2 Optimization (Expanded in v1.7.4): Zero-LLM Fast Return for data-heavy and read-only tools
|
|
510
|
+
// If all tools already return perfectly formatted markdown, skip the second LLM call to save 5-10s latency!
|
|
511
|
+
if (canFastReturnAll && accumulatedResults.length > 0) {
|
|
512
|
+
const finalContent = accumulatedResults.join('\n\n---\n\n');
|
|
513
|
+
exports.logger.addEntry({ role: 'assistant', content: finalContent }, sessionId);
|
|
514
|
+
return finalContent;
|
|
515
|
+
}
|
|
453
516
|
// Second call to get the final answer after tool execution
|
|
454
517
|
const secondMessages = [
|
|
455
518
|
{ role: 'system', content: getSystemPrompt() },
|
|
@@ -0,0 +1,36 @@
|
|
|
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.loadDefiKeys = loadDefiKeys;
|
|
7
|
+
exports.saveDefiKeys = saveDefiKeys;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
10
|
+
const paths_1 = require("./paths");
|
|
11
|
+
function loadDefiKeys() {
|
|
12
|
+
const configPath = (0, paths_1.getPath)('defi_keys.yaml');
|
|
13
|
+
try {
|
|
14
|
+
if (!fs_1.default.existsSync(configPath)) {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
const file = fs_1.default.readFileSync(configPath, 'utf8');
|
|
18
|
+
return yaml_1.default.parse(file) || {};
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
console.error('[DefiConfig] Failed to load defi_keys.yaml', e);
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function saveDefiKeys(newKeys) {
|
|
26
|
+
const configPath = (0, paths_1.getPath)('defi_keys.yaml');
|
|
27
|
+
try {
|
|
28
|
+
const currentKeys = loadDefiKeys();
|
|
29
|
+
const merged = { ...currentKeys, ...newKeys };
|
|
30
|
+
const yamlStr = yaml_1.default.stringify(merged);
|
|
31
|
+
fs_1.default.writeFileSync(configPath, yamlStr, 'utf8');
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
console.error('[DefiConfig] Failed to save defi_keys.yaml', e);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -52,7 +52,7 @@ function loadConfig() {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
return {
|
|
55
|
-
agent: parsed.agent || { name: 'Nyxora-Default', description: 'Your Personal Web3 Assistant.', default_chain: 'base', default_router: 'auto', default_slippage:
|
|
55
|
+
agent: parsed.agent || { name: 'Nyxora-Default', description: 'Your Personal Web3 Assistant.', default_chain: 'base', default_router: 'auto', default_slippage: 'auto' },
|
|
56
56
|
llm: parsed.llm || {
|
|
57
57
|
provider: 'openai',
|
|
58
58
|
model: 'gpt-4o-mini',
|
|
@@ -88,7 +88,7 @@ function loadConfig() {
|
|
|
88
88
|
description: "Your Personal Web3 Assistant.",
|
|
89
89
|
default_chain: "ethereum",
|
|
90
90
|
default_router: "auto",
|
|
91
|
-
default_slippage:
|
|
91
|
+
default_slippage: "auto"
|
|
92
92
|
},
|
|
93
93
|
llm: {
|
|
94
94
|
provider: 'openai',
|