nyxora 26.6.24 → 26.6.25
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 +20 -49
- package/dist/packages/core/src/agent/llmProvider.js +46 -33
- package/dist/packages/core/src/agent/osAgent.js +11 -123
- package/dist/packages/core/src/agent/reasoning.js +1 -3
- package/dist/packages/core/src/agent/web3Agent.js +11 -127
- package/dist/packages/core/src/config/marketConfigManager.js +43 -0
- package/dist/packages/core/src/gateway/cli.js +1 -1
- package/dist/packages/core/src/gateway/server.js +87 -91
- package/dist/packages/core/src/plugin/PluginManager.js +39 -0
- package/dist/packages/core/src/plugin/registry.js +81 -0
- package/dist/packages/core/src/plugin/registry.test.js +38 -0
- package/dist/packages/core/src/plugin/types.js +2 -0
- package/dist/packages/core/src/system/plugins/GoogleWorkspacePlugin.js +34 -0
- package/dist/packages/core/src/system/plugins/SystemCorePlugin.js +38 -0
- package/dist/packages/core/src/system/plugins/SystemPluginInstallerPlugin.js +85 -0
- package/dist/packages/core/src/system/plugins/SystemSocialPlugin.js +23 -0
- package/dist/packages/core/src/system/plugins/SystemWebPlugin.js +38 -0
- package/dist/packages/core/src/system/plugins/SystemWorkspacePlugin.js +43 -0
- package/dist/packages/core/src/web3/Web3DefiPlugin.js +28 -0
- package/dist/packages/core/src/web3/aggregator/defiRouter.js +12 -12
- package/dist/packages/core/src/web3/aggregator/providerHealthService.js +47 -0
- package/dist/packages/core/src/web3/aggregator/providerRegistry.js +118 -0
- package/dist/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.js +62 -0
- package/dist/packages/core/src/web3/aggregator/providers/KyberSwapProvider.js +87 -0
- package/dist/packages/core/src/web3/aggregator/providers/LifiProvider.js +80 -0
- package/dist/packages/core/src/web3/aggregator/providers/OneInchProvider.js +85 -0
- package/dist/packages/core/src/web3/aggregator/providers/OpBridgeProvider.js +72 -0
- package/dist/packages/core/src/web3/aggregator/providers/OpenOceanProvider.js +32 -0
- package/dist/packages/core/src/web3/aggregator/providers/RelayProvider.js +90 -0
- package/dist/packages/core/src/web3/aggregator/providers/ZeroXProvider.js +80 -0
- package/dist/packages/core/src/web3/aggregator/quoteValidator.js +36 -0
- package/dist/packages/core/src/web3/aggregator/routeScorer.js +31 -0
- package/dist/packages/core/src/web3/aggregator/routeSelector.js +79 -0
- package/dist/packages/core/src/web3/aggregator/types.js +2 -0
- package/dist/packages/core/src/web3/plugins/Web3DefiPlugin.js +68 -0
- package/dist/packages/core/src/web3/plugins/Web3SecurityPlugin.js +34 -0
- package/dist/packages/core/src/web3/plugins/Web3WalletPlugin.js +51 -0
- package/dist/packages/core/src/web3/skills/bridgeToken.js +4 -4
- package/dist/packages/core/src/web3/skills/getPrice.js +7 -2
- package/dist/packages/core/src/web3/skills/installDefiProvider.js +76 -0
- package/dist/packages/core/src/web3/skills/marketAnalysis.js +7 -2
- package/dist/packages/core/src/web3/skills/swapToken.js +5 -5
- package/dist/packages/core/src/web3/utils/marketEngine.js +32 -27
- package/package.json +1 -2
- package/packages/core/package.json +0 -1
- package/packages/core/src/agent/llmProvider.ts +58 -39
- package/packages/core/src/agent/osAgent.ts +10 -136
- package/packages/core/src/agent/reasoning.ts +1 -3
- package/packages/core/src/agent/web3Agent.ts +11 -171
- package/packages/core/src/config/marketConfigManager.ts +39 -0
- package/packages/core/src/gateway/cli.ts +1 -1
- package/packages/core/src/gateway/server.ts +94 -98
- package/packages/core/src/plugin/PluginManager.ts +42 -0
- package/packages/core/src/plugin/registry.test.ts +46 -0
- package/packages/core/src/plugin/registry.ts +46 -0
- package/packages/core/src/plugin/types.ts +13 -0
- package/packages/core/src/system/plugins/GoogleWorkspacePlugin.ts +45 -0
- package/packages/core/src/system/plugins/SystemCorePlugin.ts +38 -0
- package/packages/core/src/system/plugins/SystemPluginInstallerPlugin.ts +88 -0
- package/packages/core/src/system/plugins/SystemSocialPlugin.ts +23 -0
- package/packages/core/src/system/plugins/SystemWebPlugin.ts +38 -0
- package/packages/core/src/system/plugins/SystemWorkspacePlugin.ts +43 -0
- package/packages/core/src/web3/aggregator/defiRouter.ts +14 -12
- package/packages/core/src/web3/aggregator/providerHealthService.ts +51 -0
- package/packages/core/src/web3/aggregator/providerRegistry.ts +90 -0
- package/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.ts +64 -0
- package/packages/core/src/web3/aggregator/providers/KyberSwapProvider.ts +88 -0
- package/packages/core/src/web3/aggregator/providers/LifiProvider.ts +81 -0
- package/packages/core/src/web3/aggregator/providers/OneInchProvider.ts +89 -0
- package/packages/core/src/web3/aggregator/providers/OpBridgeProvider.ts +76 -0
- package/packages/core/src/web3/aggregator/providers/OpenOceanProvider.ts +34 -0
- package/packages/core/src/web3/aggregator/providers/RelayProvider.ts +94 -0
- package/packages/core/src/web3/aggregator/providers/ZeroXProvider.ts +80 -0
- package/packages/core/src/web3/aggregator/quoteValidator.ts +42 -0
- package/packages/core/src/web3/aggregator/routeScorer.ts +34 -0
- package/packages/core/src/web3/aggregator/routeSelector.ts +95 -0
- package/packages/core/src/web3/aggregator/types.ts +98 -0
- package/packages/core/src/web3/plugins/Web3DefiPlugin.ts +76 -0
- package/packages/core/src/web3/plugins/Web3SecurityPlugin.ts +34 -0
- package/packages/core/src/web3/plugins/Web3WalletPlugin.ts +51 -0
- package/packages/core/src/web3/skills/bridgeToken.ts +4 -4
- package/packages/core/src/web3/skills/getPrice.ts +9 -2
- package/packages/core/src/web3/skills/installDefiProvider.ts +83 -0
- package/packages/core/src/web3/skills/marketAnalysis.ts +9 -2
- package/packages/core/src/web3/skills/swapToken.ts +5 -5
- package/packages/core/src/web3/utils/marketEngine.ts +44 -38
- package/packages/dashboard/dist/assets/index-BW-OzhTX.js +16 -0
- package/packages/dashboard/dist/index.html +1 -1
- package/packages/core/src/gateway/test.ts +0 -16
- package/packages/core/src/test_security.ts +0 -45
- package/packages/core/src/web3/aggregator/aggregatorMainnet.ts +0 -293
- package/packages/core/src/web3/aggregator/aggregatorTestnet.ts +0 -146
- package/packages/core/src/web3/skills/nativeOpBridge.ts +0 -84
- package/packages/dashboard/dist/assets/index-BLMS9VtQ.js +0 -16
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
[](#)
|
|
6
|
-
[](https://base.org/)
|
|
7
7
|
[](#)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
9
|
[](#️-advanced-security-threat-model)
|
|
@@ -21,9 +21,9 @@ It operates under a **Zero-Trust, Defense-in-Depth Cryptographically Bound Human
|
|
|
21
21
|
## 🔥 Key Features
|
|
22
22
|
|
|
23
23
|
### Advanced Security Architecture
|
|
24
|
-
* **🛡️ On-Chain AI Kill-Switch**: Nyxora is governed by
|
|
24
|
+
* **🛡️ On-Chain AI Kill-Switch**: Nyxora is governed by a Base 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 Base Architecture](https://nyxoraai.github.io/Nyxora/security/smart-contract)
|
|
25
25
|
* **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).
|
|
26
|
-
* **DeFi Configuration BYOK & UI Masking**: All aggregator and
|
|
26
|
+
* **DeFi & Market Configuration BYOK & UI Masking**: All aggregator, provider, and oracle API keys are strictly isolated via a Bring Your Own Keys (BYOK) architecture into heavily guarded `~/.nyxora/defi_keys.yaml` and `~/.nyxora/market_keys.yaml` files. The local web Dashboard masks these injected secrets using `***********` and `IS_SET` censorship, completely neutralizing malicious browser extensions from exfiltrating your keys.
|
|
27
27
|
* **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.
|
|
28
28
|
* **Native Asset Parameter Tampering Protection**: The internal cryptographic HMAC signature rigorously binds `toAddress`, `txData`, and `valueWei`, rendering the system mathematically immune to Native Token (ETH/BNB) destination or amount hijacking via Indirect Prompt Injections.
|
|
29
29
|
* **Human-in-the-Loop Memory Approval**: AI-extracted permanent behavioral rules are strictly quarantined in a `pending` state until explicitly authorized by the user via the Dashboard, neutralizing Persistent Memory Poisoning vectors.
|
|
@@ -35,10 +35,10 @@ It operates under a **Zero-Trust, Defense-in-Depth Cryptographically Bound Human
|
|
|
35
35
|
### 🌐 Web3 Skills (On-Chain)
|
|
36
36
|
* **Security Scanner**: Nyxora can scan smart contracts via GoPlus Labs to detect Honeypots, Hidden Taxes, and malicious proxy upgrades before you buy.
|
|
37
37
|
* **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.
|
|
38
|
-
* **
|
|
38
|
+
* **Extensible 8-Engine Meta-Aggregator & Anti-MEV**: The core engine interfaces with a powerful, extensible Meta-Aggregator (**1inch, 0x, LI.FI, Relay, OpenOcean, KyberSwap, ArbitrumBridge, and OpBridge**) via a dynamic Provider Registry to route tokens cross-chain, ensuring absolute maximum liquidity depth.
|
|
39
39
|
* **Adaptive Auto Slippage Protection**: Nyxora enforces a dynamic and adaptive **'auto' slippage** by default to leverage dynamic MEV-protection from these industry-standard 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"*).
|
|
40
40
|
|
|
41
|
-
* **Dual-Routing Market Intelligence Engine**: Real-time asset tracking utilizing a sophisticated API Waterfall. Symbol queries are routed to CoinGecko/
|
|
41
|
+
* **Dual-Routing Market Intelligence & Smart Fallback Engine**: Real-time asset tracking utilizing a sophisticated API Waterfall. Symbol queries are routed to CoinGecko/CoinMarketCap Pro endpoints (if BYOK is configured) or gracefully fall back to public endpoints. Contract Addresses seamlessly trigger DexScreener for live on-chain liquidity metrics across all networks, guaranteeing robust discovery even for unlisted memecoins.
|
|
42
42
|
* **Asynchronous Watchdog Agents**: Seamlessly spawn detached background instances for long-running monitoring tasks (e.g., *"Notify me when $ETH drops below $2500"*), leaving your primary chat session free for other operations.
|
|
43
43
|
* **"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.
|
|
44
44
|
* **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.
|
|
@@ -95,58 +95,27 @@ To dive deeper into the technical details of our Zero-Knowledge security archite
|
|
|
95
95
|
|
|
96
96
|
---
|
|
97
97
|
|
|
98
|
-
##
|
|
98
|
+
## 🚀 Quick Start & Installation
|
|
99
99
|
|
|
100
|
-
### Global Installation
|
|
101
|
-
|
|
100
|
+
### Option 1: Global Installation (Recommended)
|
|
101
|
+
Nyxora can be installed globally via NPM, allowing you to use the `nyxora` CLI command from anywhere on your machine.
|
|
102
102
|
|
|
103
|
-
The fastest way to install Nyxora is via our automated installation script:
|
|
104
|
-
|
|
105
|
-
**For Linux & macOS (Bash):**
|
|
106
103
|
```bash
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
**For Windows (PowerShell):**
|
|
111
|
-
```powershell
|
|
112
|
-
iwr https://nyxoraai.github.io/Nyxora/install.ps1 -useb | iex
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Alternatively, you can install it manually on any operating system using NPM:
|
|
104
|
+
# Install globally
|
|
105
|
+
npm install -g nyxora
|
|
116
106
|
|
|
117
|
-
|
|
118
|
-
npm install -g nyxora@latest
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### 2. Run the Interactive Setup Wizard (API Keys, Wallet, Telegram)
|
|
122
|
-
```bash
|
|
107
|
+
# Run the interactive setup wizard (API Keys, Wallet, Telegram)
|
|
123
108
|
nyxora setup
|
|
124
|
-
```
|
|
125
109
|
|
|
126
|
-
|
|
127
|
-
```bash
|
|
110
|
+
# Start the background daemon
|
|
128
111
|
nyxora start
|
|
129
|
-
```
|
|
130
112
|
|
|
131
|
-
|
|
132
|
-
```bash
|
|
113
|
+
# Open the interactive UI dashboard
|
|
133
114
|
nyxora dashboard
|
|
134
115
|
```
|
|
135
116
|
|
|
136
|
-
###
|
|
137
|
-
|
|
138
|
-
nyxora clear --force
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Utility: Clean Uninstallation
|
|
142
|
-
To completely remove Nyxora, wipe the AI's local memory, and securely delete your Private Key from the OS Keyring before uninstalling the NPM package:
|
|
143
|
-
```bash
|
|
144
|
-
nyxora uninstall
|
|
145
|
-
```
|
|
146
|
-
> **⚠️ IMPORTANT:** Whenever you re-run `nyxora setup` or manually edit the config files, you **must restart the daemon** by running `nyxora restart` for the changes to take effect.
|
|
147
|
-
|
|
148
|
-
### Local Development (From Source)
|
|
149
|
-
If you wish to modify the code or run from source, you can use the Monorepo architecture.
|
|
117
|
+
### Option 2: Local Development (Source Code)
|
|
118
|
+
Nyxora operates on a Monorepo architecture. To run it locally from the source code, modify its behaviors, or contribute to the repository, follow these steps:
|
|
150
119
|
|
|
151
120
|
```bash
|
|
152
121
|
git clone https://github.com/nyxoraAI/Nyxora.git
|
|
@@ -158,14 +127,16 @@ npm install
|
|
|
158
127
|
# 2. Build the Dashboard UI
|
|
159
128
|
npm run build
|
|
160
129
|
|
|
161
|
-
# 3. Interactive Setup Wizard
|
|
130
|
+
# 3. Interactive Setup Wizard
|
|
162
131
|
npm run setup
|
|
163
132
|
|
|
164
133
|
# 4. Start the Application
|
|
165
134
|
npm start
|
|
166
135
|
```
|
|
136
|
+
|
|
167
137
|
*(If you are actively developing and modifying the source code, use `npm run dev` to enable hot-reloading for the frontend and backend).*
|
|
168
|
-
|
|
138
|
+
|
|
139
|
+
> **⚠️ IMPORTANT:** Whenever you re-run `nyxora setup` or manually edit the config files, you **must restart the server** for the changes to take effect.
|
|
169
140
|
|
|
170
141
|
---
|
|
171
142
|
|
|
@@ -188,7 +159,7 @@ For complete technical deep-dives into our Cryptographic Architecture, please vi
|
|
|
188
159
|
**❤️ Support the Project**
|
|
189
160
|
|
|
190
161
|
Building and maintaining a highly secure, zero-trust architecture takes significant time and resources. If you love what we are building, you can help us keep Nyxora open, secure, and constantly evolving by sending a coffee our way:
|
|
191
|
-
- **EVM :** `
|
|
162
|
+
- **EVM :** `0xF5726f0F185d6304f30c9BAE95c477471E29F14f`
|
|
192
163
|
|
|
193
164
|
---
|
|
194
165
|
**License:** MIT License
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GeminiAdapter = exports.AnthropicAdapter = exports.OpenAIAdapter = void 0;
|
|
4
|
-
const genai_1 = require("@google/genai");
|
|
5
4
|
class OpenAIAdapter {
|
|
6
5
|
client;
|
|
7
6
|
constructor(client) {
|
|
@@ -131,20 +130,20 @@ class AnthropicAdapter {
|
|
|
131
130
|
}
|
|
132
131
|
exports.AnthropicAdapter = AnthropicAdapter;
|
|
133
132
|
class GeminiAdapter {
|
|
134
|
-
|
|
135
|
-
constructor(
|
|
136
|
-
this.
|
|
133
|
+
apiKey;
|
|
134
|
+
constructor(apiKey) {
|
|
135
|
+
this.apiKey = apiKey;
|
|
137
136
|
}
|
|
138
137
|
async chat(request) {
|
|
139
138
|
let systemInstruction = '';
|
|
140
|
-
const
|
|
139
|
+
const contents = [];
|
|
141
140
|
for (const m of request.messages) {
|
|
142
141
|
if (m.role === 'system') {
|
|
143
142
|
systemInstruction = m.content;
|
|
144
143
|
continue;
|
|
145
144
|
}
|
|
146
145
|
if (m.role === 'user') {
|
|
147
|
-
|
|
146
|
+
contents.push({ role: 'user', parts: [{ text: m.content }] });
|
|
148
147
|
}
|
|
149
148
|
else if (m.role === 'assistant') {
|
|
150
149
|
const parts = [];
|
|
@@ -163,10 +162,10 @@ class GeminiAdapter {
|
|
|
163
162
|
catch (e) { }
|
|
164
163
|
});
|
|
165
164
|
}
|
|
166
|
-
|
|
165
|
+
contents.push({ role: 'model', parts: parts });
|
|
167
166
|
}
|
|
168
167
|
else if (m.role === 'tool') {
|
|
169
|
-
|
|
168
|
+
contents.push({
|
|
170
169
|
role: 'user',
|
|
171
170
|
parts: [{
|
|
172
171
|
functionResponse: {
|
|
@@ -177,18 +176,19 @@ class GeminiAdapter {
|
|
|
177
176
|
});
|
|
178
177
|
}
|
|
179
178
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
// Merge adjacent messages of the same role
|
|
180
|
+
const mergedContents = [];
|
|
181
|
+
for (const m of contents) {
|
|
182
|
+
const last = mergedContents[mergedContents.length - 1];
|
|
183
183
|
if (last && last.role === m.role) {
|
|
184
184
|
last.parts.push(...m.parts);
|
|
185
185
|
}
|
|
186
186
|
else {
|
|
187
|
-
|
|
187
|
+
mergedContents.push(m);
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
let tools = undefined;
|
|
191
|
-
if (request.tools) {
|
|
191
|
+
if (request.tools && request.tools.length > 0) {
|
|
192
192
|
tools = [{
|
|
193
193
|
functionDeclarations: request.tools.map(t => ({
|
|
194
194
|
name: t.function.name,
|
|
@@ -197,32 +197,45 @@ class GeminiAdapter {
|
|
|
197
197
|
}))
|
|
198
198
|
}];
|
|
199
199
|
}
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
200
|
+
const payload = {
|
|
201
|
+
contents: mergedContents,
|
|
202
|
+
generationConfig: {
|
|
203
|
+
temperature: request.temperature || 0.7,
|
|
204
|
+
},
|
|
205
|
+
safetySettings: [
|
|
206
|
+
{ category: 'HARM_CATEGORY_DANGEROUS_CONTENT', threshold: 'BLOCK_NONE' },
|
|
207
|
+
{ category: 'HARM_CATEGORY_HARASSMENT', threshold: 'BLOCK_NONE' },
|
|
208
|
+
{ category: 'HARM_CATEGORY_HATE_SPEECH', threshold: 'BLOCK_NONE' },
|
|
209
|
+
{ category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', threshold: 'BLOCK_NONE' }
|
|
210
|
+
]
|
|
211
|
+
};
|
|
212
|
+
if (systemInstruction) {
|
|
213
|
+
payload.systemInstruction = { parts: [{ text: systemInstruction }] };
|
|
214
|
+
}
|
|
215
|
+
if (tools) {
|
|
216
|
+
payload.tools = tools;
|
|
217
|
+
}
|
|
218
|
+
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${request.model}:generateContent?key=${this.apiKey}`, {
|
|
219
|
+
method: 'POST',
|
|
220
|
+
headers: {
|
|
221
|
+
'Content-Type': 'application/json'
|
|
222
|
+
},
|
|
223
|
+
body: JSON.stringify(payload)
|
|
214
224
|
});
|
|
225
|
+
if (!response.ok) {
|
|
226
|
+
const errText = await response.text();
|
|
227
|
+
throw new Error(`Gemini API Error: ${response.status} ${response.statusText} - ${errText}`);
|
|
228
|
+
}
|
|
229
|
+
const data = await response.json();
|
|
215
230
|
let contentStr = null;
|
|
216
231
|
let toolCalls = [];
|
|
217
|
-
if (
|
|
218
|
-
const candidate =
|
|
219
|
-
// Log finish reason for debugging safety blocks
|
|
232
|
+
if (data.candidates && data.candidates.length > 0) {
|
|
233
|
+
const candidate = data.candidates[0];
|
|
220
234
|
if (candidate.finishReason && candidate.finishReason !== 'STOP') {
|
|
221
235
|
console.warn(`[LLM] Gemini API returned finishReason: ${candidate.finishReason}`);
|
|
222
236
|
}
|
|
223
237
|
if (candidate.content && candidate.content.parts) {
|
|
224
|
-
const
|
|
225
|
-
for (const part of parts) {
|
|
238
|
+
for (const part of candidate.content.parts) {
|
|
226
239
|
if (part.text) {
|
|
227
240
|
contentStr = (contentStr || '') + part.text;
|
|
228
241
|
}
|
|
@@ -232,7 +245,7 @@ class GeminiAdapter {
|
|
|
232
245
|
type: 'function',
|
|
233
246
|
function: {
|
|
234
247
|
name: part.functionCall.name,
|
|
235
|
-
arguments: JSON.stringify(part.functionCall.args)
|
|
248
|
+
arguments: JSON.stringify(part.functionCall.args || {})
|
|
236
249
|
}
|
|
237
250
|
});
|
|
238
251
|
}
|
|
@@ -12,25 +12,7 @@ const logger_1 = require("../memory/logger");
|
|
|
12
12
|
const tracker_1 = require("../gateway/tracker");
|
|
13
13
|
const episodic_1 = require("../memory/episodic");
|
|
14
14
|
const skillManager_1 = require("../utils/skillManager");
|
|
15
|
-
const
|
|
16
|
-
const updateIdentity_1 = require("./updateIdentity");
|
|
17
|
-
const updateSecurityPolicy_1 = require("../system/skills/updateSecurityPolicy");
|
|
18
|
-
const analyzeDocument_1 = require("../system/skills/analyzeDocument");
|
|
19
|
-
const readFile_1 = require("../system/skills/readFile");
|
|
20
|
-
const writeFile_1 = require("../system/skills/writeFile");
|
|
21
|
-
const generateExcel_1 = require("../system/skills/generateExcel");
|
|
22
|
-
const executeShell_1 = require("../system/skills/executeShell");
|
|
23
|
-
const browseWeb_1 = require("../system/skills/browseWeb");
|
|
24
|
-
const searchWeb_1 = require("../system/skills/searchWeb");
|
|
25
|
-
const editFile_1 = require("../system/skills/editFile");
|
|
26
|
-
const gitManager_1 = require("../system/skills/gitManager");
|
|
27
|
-
const xManager_1 = require("../system/skills/xManager");
|
|
28
|
-
const notionWorkspace_1 = require("../system/skills/notionWorkspace");
|
|
29
|
-
const audioTranscribe_1 = require("../system/skills/audioTranscribe");
|
|
30
|
-
const summarizeText_1 = require("../system/skills/summarizeText");
|
|
31
|
-
const scheduleTask_1 = require("../system/skills/scheduleTask");
|
|
32
|
-
const cancelTask_1 = require("../system/skills/cancelTask");
|
|
33
|
-
const googleWorkspace_1 = require("../system/skills/googleWorkspace");
|
|
15
|
+
const registry_1 = require("../plugin/registry");
|
|
34
16
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
35
17
|
exports.logger = new logger_1.Logger();
|
|
36
18
|
const PROVIDER_CONFIGS = {
|
|
@@ -137,10 +119,8 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
|
|
|
137
119
|
exports.logger.addEntry({ role, content: input }, sessionId);
|
|
138
120
|
const history = exports.logger.getHistory(sessionId);
|
|
139
121
|
// Format messages for OpenAI
|
|
140
|
-
let activeTools = [];
|
|
141
|
-
|
|
142
|
-
const GOOGLE_TOOLS = [googleWorkspace_1.readGmailInboxToolDefinition, googleWorkspace_1.listCalendarEventsToolDefinition, googleWorkspace_1.appendRowToSheetsToolDefinition, googleWorkspace_1.readGoogleDocsToolDefinition, googleWorkspace_1.readGoogleFormResponsesToolDefinition];
|
|
143
|
-
activeTools = [...SYSTEM_TOOLS, ...GOOGLE_TOOLS].filter(t => (0, skillManager_1.isSkillActive)(t.function.name));
|
|
122
|
+
let activeTools = [...registry_1.pluginManager.getAllToolDefinitions()];
|
|
123
|
+
activeTools = activeTools.filter(t => (0, skillManager_1.isSkillActive)(t.function.name));
|
|
144
124
|
const { sanitizeHistoryForLLM } = require('../utils/historySanitizer');
|
|
145
125
|
const sanitizedHistory = sanitizeHistoryForLLM(history, activeTools);
|
|
146
126
|
let messages = [
|
|
@@ -149,9 +129,7 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
|
|
|
149
129
|
];
|
|
150
130
|
try {
|
|
151
131
|
const context = 'os';
|
|
152
|
-
|
|
153
|
-
const GOOGLE_TOOLS = [googleWorkspace_1.readGmailInboxToolDefinition, googleWorkspace_1.listCalendarEventsToolDefinition, googleWorkspace_1.appendRowToSheetsToolDefinition, googleWorkspace_1.readGoogleDocsToolDefinition, googleWorkspace_1.readGoogleFormResponsesToolDefinition];
|
|
154
|
-
let activeTools = [...SYSTEM_TOOLS, ...GOOGLE_TOOLS];
|
|
132
|
+
let activeTools = [...registry_1.pluginManager.getAllToolDefinitions()];
|
|
155
133
|
activeTools = activeTools.filter(t => (0, skillManager_1.isSkillActive)(t.function.name));
|
|
156
134
|
const response = await executeWithRetry(async (client) => {
|
|
157
135
|
return await client.chat.completions.create({
|
|
@@ -214,103 +192,13 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
|
|
|
214
192
|
continue;
|
|
215
193
|
}
|
|
216
194
|
try {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
case 'update_security_policy': {
|
|
227
|
-
result = await (0, updateSecurityPolicy_1.updateSecurityPolicy)(args.policy, args.action || 'add');
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
case 'analyze_document': {
|
|
231
|
-
result = await (0, analyzeDocument_1.analyzeDocument)(args.filePath);
|
|
232
|
-
break;
|
|
233
|
-
}
|
|
234
|
-
case 'read_local_file': {
|
|
235
|
-
result = (0, readFile_1.readLocalFile)(args.filePath, args.startLine, args.endLine);
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
case 'edit_local_file': {
|
|
239
|
-
result = (0, editFile_1.editLocalFile)(args.filePath, args.searchString, args.replacementString);
|
|
240
|
-
break;
|
|
241
|
-
}
|
|
242
|
-
case 'execute_git_command': {
|
|
243
|
-
result = await (0, gitManager_1.executeGitCommand)(args.action, args.commitMessage);
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
case 'manage_twitter': {
|
|
247
|
-
result = await (0, xManager_1.manageTwitter)(args.action, args.content, args.username);
|
|
248
|
-
break;
|
|
249
|
-
}
|
|
250
|
-
case 'manage_notion': {
|
|
251
|
-
result = await (0, notionWorkspace_1.manageNotion)(args.action, args.pageId, args.text);
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
254
|
-
case 'transcribe_audio': {
|
|
255
|
-
result = await (0, audioTranscribe_1.transcribeAudio)(args.filePath);
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
case 'summarize_text': {
|
|
259
|
-
result = await (0, summarizeText_1.summarizeText)(args.text, args.focus);
|
|
260
|
-
break;
|
|
261
|
-
}
|
|
262
|
-
case 'write_local_file': {
|
|
263
|
-
result = (0, writeFile_1.writeLocalFile)(args.filePath, args.content);
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
case 'generate_excel_file': {
|
|
267
|
-
result = await (0, generateExcel_1.generateExcelFile)(args.data, args.filePath);
|
|
268
|
-
break;
|
|
269
|
-
}
|
|
270
|
-
case 'run_terminal_command': {
|
|
271
|
-
result = await (0, executeShell_1.runTerminalCommand)(args.command);
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
|
-
case 'browse_website': {
|
|
275
|
-
result = await (0, browseWeb_1.browseWebsite)(args.url);
|
|
276
|
-
break;
|
|
277
|
-
}
|
|
278
|
-
case 'search_web': {
|
|
279
|
-
result = await (0, searchWeb_1.searchWeb)(args.query, args.depth);
|
|
280
|
-
break;
|
|
281
|
-
}
|
|
282
|
-
case 'schedule_task': {
|
|
283
|
-
result = await (0, scheduleTask_1.executeScheduleTask)(args);
|
|
284
|
-
break;
|
|
285
|
-
}
|
|
286
|
-
case 'cancel_task': {
|
|
287
|
-
result = await (0, cancelTask_1.executeCancelTask)(args);
|
|
288
|
-
break;
|
|
289
|
-
}
|
|
290
|
-
case 'read_gmail_inbox': {
|
|
291
|
-
result = await (0, googleWorkspace_1.readGmailInbox)(args.maxResults);
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
case 'list_calendar_events': {
|
|
295
|
-
result = await (0, googleWorkspace_1.listCalendarEvents)(args.maxResults);
|
|
296
|
-
break;
|
|
297
|
-
}
|
|
298
|
-
case 'append_row_to_sheets': {
|
|
299
|
-
result = await (0, googleWorkspace_1.appendRowToSheets)(args.spreadsheetId, args.range, args.values);
|
|
300
|
-
break;
|
|
301
|
-
}
|
|
302
|
-
case 'read_google_docs': {
|
|
303
|
-
result = await (0, googleWorkspace_1.readGoogleDocs)(args.documentId);
|
|
304
|
-
break;
|
|
305
|
-
}
|
|
306
|
-
case 'read_google_form_responses': {
|
|
307
|
-
result = await (0, googleWorkspace_1.readGoogleFormResponses)(args.formId);
|
|
308
|
-
break;
|
|
309
|
-
}
|
|
310
|
-
default: {
|
|
311
|
-
result = `Error: Tool ${toolName} is not implemented.`;
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
195
|
+
// 1. Execute via PluginManager
|
|
196
|
+
const pluginResult = await registry_1.pluginManager.executeTool(toolName, args, { sessionId });
|
|
197
|
+
if (pluginResult !== null) {
|
|
198
|
+
result = pluginResult;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
result = `Error: Tool ${toolName} is not implemented.`;
|
|
314
202
|
}
|
|
315
203
|
if (result.includes('[Security Blocked]') || result.startsWith('Error:')) {
|
|
316
204
|
console.log(picocolors_1.default.red(`[❌ Failed] Tool ${toolName} returned an error or was blocked.`));
|
|
@@ -11,7 +11,6 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
11
11
|
const openai_1 = require("openai");
|
|
12
12
|
const llmProvider_1 = require("./llmProvider");
|
|
13
13
|
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
14
|
-
const genai_1 = require("@google/genai");
|
|
15
14
|
const parser_1 = require("../config/parser");
|
|
16
15
|
const logger_1 = require("../memory/logger");
|
|
17
16
|
const episodic_1 = require("../memory/episodic");
|
|
@@ -73,8 +72,7 @@ async function getLLMClient() {
|
|
|
73
72
|
return new llmProvider_1.AnthropicAdapter(client);
|
|
74
73
|
}
|
|
75
74
|
if (providerName === 'gemini') {
|
|
76
|
-
|
|
77
|
-
return new llmProvider_1.GeminiAdapter(client);
|
|
75
|
+
return new llmProvider_1.GeminiAdapter(apiKey);
|
|
78
76
|
}
|
|
79
77
|
// Default fallback (OpenAI, Groq, OpenRouter, xAI, Mistral, DeepSeek)
|
|
80
78
|
const providerConf = PROVIDER_CONFIGS[providerName] || PROVIDER_CONFIGS['openai'];
|
|
@@ -11,30 +11,8 @@ const parser_1 = require("../config/parser");
|
|
|
11
11
|
const logger_1 = require("../memory/logger");
|
|
12
12
|
const tracker_1 = require("../gateway/tracker");
|
|
13
13
|
const episodic_1 = require("../memory/episodic");
|
|
14
|
-
const getBalance_1 = require("../web3/skills/getBalance");
|
|
15
|
-
const transfer_1 = require("../web3/skills/transfer");
|
|
16
|
-
const getPrice_1 = require("../web3/skills/getPrice");
|
|
17
|
-
const swapToken_1 = require("../web3/skills/swapToken");
|
|
18
|
-
const bridgeToken_1 = require("../web3/skills/bridgeToken");
|
|
19
14
|
const skillManager_1 = require("../utils/skillManager");
|
|
20
|
-
const
|
|
21
|
-
const customTx_1 = require("../web3/skills/customTx");
|
|
22
|
-
const checkSecurity_1 = require("../web3/skills/checkSecurity");
|
|
23
|
-
const marketAnalysis_1 = require("../web3/skills/marketAnalysis");
|
|
24
|
-
const createMarketWatchAgent_1 = require("../web3/skills/createMarketWatchAgent");
|
|
25
|
-
const checkPortfolio_1 = require("../web3/skills/checkPortfolio");
|
|
26
|
-
const checkAddress_1 = require("../web3/skills/checkAddress");
|
|
27
|
-
const getMyAddress_1 = require("../web3/skills/getMyAddress");
|
|
28
|
-
const manageCustomTokens_1 = require("../web3/skills/manageCustomTokens");
|
|
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");
|
|
34
|
-
const createLimitOrder_1 = require("../web3/skills/createLimitOrder");
|
|
35
|
-
const checkRegistryStatus_1 = require("../web3/skills/checkRegistryStatus");
|
|
36
|
-
const browseWeb_1 = require("../system/skills/browseWeb");
|
|
37
|
-
const searchWeb_1 = require("../system/skills/searchWeb");
|
|
15
|
+
const registry_1 = require("../plugin/registry");
|
|
38
16
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
39
17
|
exports.logger = new logger_1.Logger();
|
|
40
18
|
const PROVIDER_CONFIGS = {
|
|
@@ -145,11 +123,9 @@ async function processWeb3Intent(input, role = 'user', onProgress, sessionId) {
|
|
|
145
123
|
exports.logger.addEntry({ role, content: input }, sessionId);
|
|
146
124
|
const history = exports.logger.getHistory(sessionId);
|
|
147
125
|
// Format messages for OpenAI
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
let activeTools = [...tools, browseWeb_1.browseWebsiteToolDefinition, searchWeb_1.searchWebToolDefinition];
|
|
126
|
+
// Inject Plugin Tools dynamically
|
|
127
|
+
const pluginTools = registry_1.pluginManager.getAllToolDefinitions();
|
|
128
|
+
let activeTools = [...pluginTools];
|
|
153
129
|
activeTools = activeTools.filter(t => (0, skillManager_1.isSkillActive)(t.function.name));
|
|
154
130
|
const { sanitizeHistoryForLLM } = require('../utils/historySanitizer');
|
|
155
131
|
const sanitizedHistory = sanitizeHistoryForLLM(history, activeTools);
|
|
@@ -223,105 +199,13 @@ async function processWeb3Intent(input, role = 'user', onProgress, sessionId) {
|
|
|
223
199
|
continue;
|
|
224
200
|
}
|
|
225
201
|
try {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
result = await (0, transfer_1.prepareTransfer)(args.chainName, args.toAddress, args.amountStr || args.amountEth, args.token);
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
case 'get_price': {
|
|
237
|
-
result = await (0, getPrice_1.getPrice)(args.coinId, args.currency);
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
case 'swap_token': {
|
|
241
|
-
result = await (0, swapToken_1.prepareSwapToken)(args.chainName, args.fromToken, args.toToken, args.amountStr || args.amount, args.mode, args.providerName);
|
|
242
|
-
break;
|
|
243
|
-
}
|
|
244
|
-
case 'bridge_token': {
|
|
245
|
-
result = await (0, bridgeToken_1.prepareBridgeToken)(args.fromChain, args.toChain, args.tokenSymbol, args.amountStr, args.mode, args.providerName);
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
case 'mint_nft': {
|
|
249
|
-
result = await (0, mintNft_1.prepareMintNft)(args.chainName, args.contractAddress, args.functionSignature, args.argsStr, args.valueEth);
|
|
250
|
-
break;
|
|
251
|
-
}
|
|
252
|
-
case 'custom_tx': {
|
|
253
|
-
result = await (0, customTx_1.prepareCustomTx)(args.chainName, args.toAddress, args.dataHex, args.valueEth, args.gasLimitStr);
|
|
254
|
-
break;
|
|
255
|
-
}
|
|
256
|
-
case 'check_token_security': {
|
|
257
|
-
result = await (0, checkSecurity_1.checkTokenSecurity)(args.chainName, args.contractAddress);
|
|
258
|
-
break;
|
|
259
|
-
}
|
|
260
|
-
case 'analyze_market': {
|
|
261
|
-
result = await (0, marketAnalysis_1.analyzeMarket)(args.chainName, args.tokenAddressOrSymbol);
|
|
262
|
-
break;
|
|
263
|
-
}
|
|
264
|
-
case 'create_market_watch_agent': {
|
|
265
|
-
result = await (0, createMarketWatchAgent_1.createMarketWatchAgent)(args.chainName, args.contractAddress, args.rules, args.durationDays);
|
|
266
|
-
break;
|
|
267
|
-
}
|
|
268
|
-
case 'check_portfolio': {
|
|
269
|
-
result = await (0, checkPortfolio_1.checkPortfolio)(args.chainName, args.address);
|
|
270
|
-
break;
|
|
271
|
-
}
|
|
272
|
-
case 'check_address': {
|
|
273
|
-
result = await (0, checkAddress_1.checkAddress)(args.chainName, args.address);
|
|
274
|
-
break;
|
|
275
|
-
}
|
|
276
|
-
case 'get_my_address': {
|
|
277
|
-
result = await (0, getMyAddress_1.getMyAddress)();
|
|
278
|
-
break;
|
|
279
|
-
}
|
|
280
|
-
case 'manage_custom_tokens': {
|
|
281
|
-
result = await (0, manageCustomTokens_1.executeManageCustomTokens)(args);
|
|
282
|
-
break;
|
|
283
|
-
}
|
|
284
|
-
case 'revoke_approval': {
|
|
285
|
-
result = await (0, revokeApprovals_1.prepareRevokeApproval)(args.chainName, args.tokenAddressOrSymbol, args.spenderAddress);
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
case 'supply_aave': {
|
|
289
|
-
result = await (0, defiLending_1.prepareAaveSupply)(args.chainName, args.tokenAddressOrSymbol, args.amountStr);
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
case 'deposit_yield_vault': {
|
|
293
|
-
result = await (0, yieldVault_1.prepareVaultDeposit)(args.chainName, args.protocol || 'beefy', args.vaultAddress, args.tokenAddressOrSymbol, args.amountStr);
|
|
294
|
-
break;
|
|
295
|
-
}
|
|
296
|
-
case 'provide_liquidity_v3': {
|
|
297
|
-
result = await (0, provideLiquidity_1.prepareProvideLiquidity)(args.chainName, args.token0AddressOrSymbol, args.token1AddressOrSymbol, args.amount0Str, args.amount1Str, args.feeTier, args.tickLower, args.tickUpper);
|
|
298
|
-
break;
|
|
299
|
-
}
|
|
300
|
-
case 'get_tx_history': {
|
|
301
|
-
result = await (0, getTxHistory_1.getTxHistory)(args.chainName, args.address, args.days);
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
case 'check_registry_status': {
|
|
305
|
-
const registryResult = await (0, checkRegistryStatus_1.checkRegistryStatus)();
|
|
306
|
-
result = JSON.stringify(registryResult);
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
309
|
-
case 'create_limit_order': {
|
|
310
|
-
result = await (0, createLimitOrder_1.createLimitOrder)(args.tokenSymbol, args.tokenAddress, args.triggerCondition, args.triggerPriceUsd, args.action, args.amountUsd, args.slippageTolerance);
|
|
311
|
-
break;
|
|
312
|
-
}
|
|
313
|
-
case 'browse_website': {
|
|
314
|
-
result = await (0, browseWeb_1.browseWebsite)(args.url);
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
|
-
case 'search_web': {
|
|
318
|
-
result = await (0, searchWeb_1.searchWeb)(args.query, args.depth);
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
default: {
|
|
322
|
-
result = `Error: Tool ${toolName} is not implemented.`;
|
|
323
|
-
break;
|
|
324
|
-
}
|
|
202
|
+
// 1. Execute via PluginManager
|
|
203
|
+
const pluginResult = await registry_1.pluginManager.executeTool(toolName, args, { sessionId });
|
|
204
|
+
if (pluginResult !== null) {
|
|
205
|
+
result = pluginResult;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
result = `Error: Tool ${toolName} is not implemented.`;
|
|
325
209
|
}
|
|
326
210
|
if (result.includes('[Security Blocked]') || result.startsWith('Error:')) {
|
|
327
211
|
console.log(picocolors_1.default.red(`[❌ Failed] Tool ${toolName} returned an error or was blocked.`));
|