nyxora 26.7.2 → 26.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/CHANGELOG.md +95 -47
  2. package/README.md +23 -19
  3. package/bin/nyxora.mjs +4 -6
  4. package/dist/launcher.js +44 -8
  5. package/dist/packages/core/src/agent/bridgeWatcher.js +3 -2
  6. package/dist/packages/core/src/agent/cronManager.js +2 -2
  7. package/dist/packages/core/src/agent/llmProvider.js +242 -0
  8. package/dist/packages/core/src/agent/nyxDaemon.js +97 -0
  9. package/dist/packages/core/src/agent/osAgent.js +203 -29
  10. package/dist/packages/core/src/agent/reasoning.js +353 -60
  11. package/dist/packages/core/src/agent/reasoningScratchpad.js +47 -0
  12. package/dist/packages/core/src/agent/transactionManager.js +36 -31
  13. package/dist/packages/core/src/agent/web3Agent.js +263 -37
  14. package/dist/packages/core/src/cognitive/cognitiveManager.js +63 -10
  15. package/dist/packages/core/src/config/parser.js +10 -4
  16. package/dist/packages/core/src/gateway/chat.js +56 -13
  17. package/dist/packages/core/src/gateway/cli.js +3 -0
  18. package/dist/packages/core/src/gateway/discordAdapter.js +81 -0
  19. package/dist/packages/core/src/gateway/server.js +58 -9
  20. package/dist/packages/core/src/gateway/setup-ml.js +64 -0
  21. package/dist/packages/core/src/gateway/setup.js +39 -3
  22. package/dist/packages/core/src/gateway/telegram.js +120 -24
  23. package/dist/packages/core/src/memory/episodic.js +47 -3
  24. package/dist/packages/core/src/memory/logger.js +120 -2
  25. package/dist/packages/core/src/memory/promotionEngine.js +18 -5
  26. package/dist/packages/core/src/system/agentskills.js +10 -0
  27. package/dist/packages/core/src/system/plugins/GoogleWorkspacePlugin.js +1 -1
  28. package/dist/packages/core/src/system/plugins/SystemCorePlugin.js +1 -1
  29. package/dist/packages/core/src/system/plugins/SystemExternalPlugin.js +1 -1
  30. package/dist/packages/core/src/system/plugins/SystemPluginInstallerPlugin.js +1 -1
  31. package/dist/packages/core/src/system/plugins/SystemSocialPlugin.js +1 -1
  32. package/dist/packages/core/src/system/plugins/SystemWebPlugin.js +1 -1
  33. package/dist/packages/core/src/system/plugins/SystemWorkspacePlugin.js +3 -3
  34. package/dist/packages/core/src/system/plugins/createSkill.js +1 -1
  35. package/dist/packages/core/src/system/skillExtractor.js +16 -5
  36. package/dist/packages/core/src/system/skills/forgetMemory.js +6 -4
  37. package/dist/packages/core/src/system/skills/scheduleTask.js +7 -2
  38. package/dist/packages/core/src/test_mainnet.js +45 -0
  39. package/dist/packages/core/src/utils/contextSummarizer.js +82 -0
  40. package/dist/packages/core/src/utils/skillManager.js +1 -1
  41. package/dist/packages/core/src/utils/streamSimulator.js +85 -0
  42. package/dist/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.js +28 -11
  43. package/dist/packages/core/src/web3/aggregator/providers/OpBridgeProvider.js +41 -27
  44. package/dist/packages/core/src/web3/aggregator/providers/TestnetSwapProvider.js +65 -0
  45. package/dist/packages/core/src/web3/aggregator/routeSelector.js +7 -1
  46. package/dist/packages/core/src/web3/plugins/Web3DefiPlugin.js +1 -1
  47. package/dist/packages/core/src/web3/plugins/Web3MarketPlugin.js +5 -125
  48. package/dist/packages/core/src/web3/plugins/Web3SecurityPlugin.js +1 -1
  49. package/dist/packages/core/src/web3/plugins/Web3WalletPlugin.js +1 -1
  50. package/dist/packages/core/src/web3/skills/bridgeToken.js +19 -4
  51. package/dist/packages/core/src/web3/skills/checkAddress.js +2 -0
  52. package/dist/packages/core/src/web3/skills/checkPortfolio.js +22 -2
  53. package/dist/packages/core/src/web3/skills/checkSecurity.js +2 -0
  54. package/dist/packages/core/src/web3/skills/confirmPendingTx.js +1 -1
  55. package/dist/packages/core/src/web3/skills/createLimitOrder.js +15 -1
  56. package/dist/packages/core/src/web3/skills/customTx.js +3 -0
  57. package/dist/packages/core/src/web3/skills/defiLending.js +2 -0
  58. package/dist/packages/core/src/web3/skills/getBalance.js +2 -0
  59. package/dist/packages/core/src/web3/skills/getPrice.js +134 -27
  60. package/dist/packages/core/src/web3/skills/getTxHistory.js +2 -0
  61. package/dist/packages/core/src/web3/skills/marketAnalysis.js +28 -191
  62. package/dist/packages/core/src/web3/skills/mintNft.js +3 -0
  63. package/dist/packages/core/src/web3/skills/provideLiquidity.js +16 -12
  64. package/dist/packages/core/src/web3/skills/revokeApprovals.js +2 -0
  65. package/dist/packages/core/src/web3/skills/swapToken.js +20 -2
  66. package/dist/packages/core/src/web3/skills/transfer.js +2 -0
  67. package/dist/packages/core/src/web3/skills/yieldVault.js +2 -0
  68. package/dist/packages/core/src/web3/utils/chains.js +19 -0
  69. package/dist/packages/core/src/web3/utils/marketEngine.js +26 -33
  70. package/dist/packages/signer/src/NyxoraSigner.js +181 -0
  71. package/dist/packages/signer/src/index.js +17 -0
  72. package/dist/packages/signer/src/server.js +25 -161
  73. package/launcher.ts +38 -9
  74. package/package.json +6 -2
  75. package/packages/core/package.json +21 -10
  76. package/packages/core/src/agent/bridgeWatcher.ts +3 -2
  77. package/packages/core/src/agent/cronManager.ts +2 -2
  78. package/packages/core/src/agent/llmProvider.ts +219 -0
  79. package/packages/core/src/agent/nyxDaemon.ts +104 -0
  80. package/packages/core/src/agent/osAgent.ts +230 -32
  81. package/packages/core/src/agent/reasoning.ts +376 -64
  82. package/packages/core/src/agent/reasoningScratchpad.ts +45 -0
  83. package/packages/core/src/agent/transactionManager.ts +36 -28
  84. package/packages/core/src/agent/web3Agent.ts +291 -40
  85. package/packages/core/src/cognitive/cognitiveManager.ts +65 -10
  86. package/packages/core/src/cognitive/prompts/web3/market-analysis.md +24 -0
  87. package/packages/core/src/cognitive/prompts/web3/portfolio-review.md +29 -0
  88. package/packages/core/src/cognitive/prompts/web3/risk-assessment.md +28 -0
  89. package/packages/core/src/cognitive/prompts/web3/trade-planning.md +30 -0
  90. package/packages/core/src/config/parser.ts +15 -4
  91. package/packages/core/src/gateway/chat.ts +57 -15
  92. package/packages/core/src/gateway/cli.ts +4 -0
  93. package/packages/core/src/gateway/discordAdapter.ts +87 -0
  94. package/packages/core/src/gateway/server.ts +66 -10
  95. package/packages/core/src/gateway/setup-ml.ts +68 -0
  96. package/packages/core/src/gateway/setup.ts +41 -3
  97. package/packages/core/src/gateway/telegram.ts +138 -27
  98. package/packages/core/src/memory/episodic.ts +64 -3
  99. package/packages/core/src/memory/logger.ts +142 -2
  100. package/packages/core/src/memory/promotionEngine.ts +19 -5
  101. package/packages/core/src/system/agentskills.ts +10 -0
  102. package/packages/core/src/system/plugins/GoogleWorkspacePlugin.ts +1 -1
  103. package/packages/core/src/system/plugins/SystemCorePlugin.ts +1 -1
  104. package/packages/core/src/system/plugins/SystemExternalPlugin.ts +1 -1
  105. package/packages/core/src/system/plugins/SystemPluginInstallerPlugin.ts +1 -1
  106. package/packages/core/src/system/plugins/SystemSocialPlugin.ts +1 -1
  107. package/packages/core/src/system/plugins/SystemWebPlugin.ts +1 -1
  108. package/packages/core/src/system/plugins/SystemWorkspacePlugin.ts +3 -3
  109. package/packages/core/src/system/plugins/createSkill.ts +1 -1
  110. package/packages/core/src/system/skillExtractor.ts +16 -5
  111. package/packages/core/src/system/skills/forgetMemory.ts +7 -4
  112. package/packages/core/src/system/skills/scheduleTask.ts +7 -2
  113. package/packages/core/src/utils/contextSummarizer.ts +100 -0
  114. package/packages/core/src/utils/skillManager.ts +1 -1
  115. package/packages/core/src/utils/streamSimulator.ts +88 -0
  116. package/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.ts +30 -11
  117. package/packages/core/src/web3/aggregator/providers/OpBridgeProvider.ts +43 -29
  118. package/packages/core/src/web3/aggregator/routeSelector.ts +6 -1
  119. package/packages/core/src/web3/plugins/Web3DefiPlugin.ts +1 -1
  120. package/packages/core/src/web3/plugins/Web3MarketPlugin.ts +6 -125
  121. package/packages/core/src/web3/plugins/Web3SecurityPlugin.ts +1 -1
  122. package/packages/core/src/web3/plugins/Web3WalletPlugin.ts +1 -1
  123. package/packages/core/src/web3/skills/bridgeToken.ts +21 -7
  124. package/packages/core/src/web3/skills/checkAddress.ts +2 -0
  125. package/packages/core/src/web3/skills/checkPortfolio.ts +23 -2
  126. package/packages/core/src/web3/skills/checkSecurity.ts +2 -0
  127. package/packages/core/src/web3/skills/confirmPendingTx.ts +1 -1
  128. package/packages/core/src/web3/skills/createLimitOrder.ts +17 -2
  129. package/packages/core/src/web3/skills/customTx.ts +3 -0
  130. package/packages/core/src/web3/skills/defiLending.ts +2 -0
  131. package/packages/core/src/web3/skills/getBalance.ts +2 -0
  132. package/packages/core/src/web3/skills/getPrice.ts +134 -30
  133. package/packages/core/src/web3/skills/getTxHistory.ts +2 -0
  134. package/packages/core/src/web3/skills/marketAnalysis.ts +45 -188
  135. package/packages/core/src/web3/skills/mintNft.ts +3 -0
  136. package/packages/core/src/web3/skills/provideLiquidity.ts +16 -10
  137. package/packages/core/src/web3/skills/revokeApprovals.ts +2 -0
  138. package/packages/core/src/web3/skills/swapToken.ts +20 -3
  139. package/packages/core/src/web3/skills/transfer.ts +2 -0
  140. package/packages/core/src/web3/skills/yieldVault.ts +2 -0
  141. package/packages/core/src/web3/utils/chains.ts +12 -0
  142. package/packages/core/src/web3/utils/marketEngine.ts +27 -33
  143. package/packages/dashboard/dist/assets/index-BTfp141V.js +18 -0
  144. package/packages/dashboard/dist/assets/index-DK2sTU47.css +1 -0
  145. package/packages/dashboard/dist/index.html +2 -2
  146. package/packages/dashboard/package.json +10 -10
  147. package/packages/mcp-server/dist/server.js +5 -1
  148. package/packages/mcp-server/package.json +6 -6
  149. package/packages/mcp-server/src/server.ts +11 -7
  150. package/packages/policy/package.json +3 -3
  151. package/packages/signer/package.json +16 -6
  152. package/packages/signer/src/NyxoraSigner.ts +161 -0
  153. package/packages/signer/src/index.ts +1 -0
  154. package/packages/signer/src/server.ts +25 -135
  155. package/dist/packages/core/src/agent/honchoDaemon.js +0 -91
  156. package/dist/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -54
  157. package/dist/packages/core/src/gateway/test.js +0 -15
  158. package/dist/packages/core/src/web3/Web3DefiPlugin.js +0 -28
  159. package/dist/packages/core/src/web3/aggregator/aggregatorMainnet.js +0 -260
  160. package/dist/packages/core/src/web3/aggregator/aggregatorTestnet.js +0 -119
  161. package/dist/packages/core/src/web3/skills/nativeOpBridge.js +0 -71
  162. package/packages/core/src/agent/honchoDaemon.ts +0 -96
  163. package/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -41
  164. package/packages/core/src/plugin/registry.test.ts +0 -46
  165. package/packages/core/src/utils/formatter.test.ts +0 -41
  166. package/packages/dashboard/dist/assets/index-CSoNa5cx.css +0 -1
  167. package/packages/dashboard/dist/assets/index-DbRWEoSr.js +0 -16
@@ -18,6 +18,10 @@ exports.scheduleTaskDefinition = {
18
18
  prompt: {
19
19
  type: "string",
20
20
  description: "The prompt/command that the AI should execute when the cron triggers. E.g., 'What is the current price of Ethereum?'"
21
+ },
22
+ languageContext: {
23
+ type: "string",
24
+ description: "Optional. The specific language constraint for the AI's response (e.g., 'Reply strictly in Indonesian informal style', 'Reply in Japanese'). Infer this automatically from the user's current conversation language."
21
25
  }
22
26
  },
23
27
  required: ["cronExpression", "prompt"]
@@ -25,12 +29,13 @@ exports.scheduleTaskDefinition = {
25
29
  }
26
30
  };
27
31
  async function executeScheduleTask(args) {
28
- const { cronExpression, prompt } = args;
32
+ const { cronExpression, prompt, languageContext } = args;
29
33
  if (!cronExpression || !prompt) {
30
34
  return "Error: Missing required parameters cronExpression or prompt.";
31
35
  }
32
36
  try {
33
- const jobId = cronManager_1.cronManager.addJob(cronExpression, prompt);
37
+ const finalPrompt = languageContext ? `${prompt}\n(System Context: ${languageContext})` : prompt;
38
+ const jobId = cronManager_1.cronManager.addJob(cronExpression, finalPrompt);
34
39
  return `Success! I have scheduled the background task.\nJob ID: ${jobId}\nSchedule: ${cronExpression}\nPrompt to execute: "${prompt}"\n\nYou will receive a notification via Telegram every time this task completes.`;
35
40
  }
36
41
  catch (error) {
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const providerRegistry_1 = require("./web3/aggregator/providerRegistry");
4
+ const routeSelector_1 = require("./web3/aggregator/routeSelector");
5
+ async function testMainnetSwap(providerName) {
6
+ try {
7
+ const req = {
8
+ fromChain: 'ethereum',
9
+ toChain: 'ethereum',
10
+ fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
11
+ toToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
12
+ amountInWei: '1000000',
13
+ amountFormatted: '1',
14
+ userAddress: '0x1234567890123456789012345678901234567890',
15
+ slippageTolerance: 50,
16
+ preferredProvider: providerName
17
+ };
18
+ console.log(`\n--- Testing ${providerName} ---`);
19
+ const quote = await (0, routeSelector_1.fetchBestRoute)(req, "best_output");
20
+ console.log(`[+] SUCCESS. Provider used: ${quote.provider}`);
21
+ console.log(` - execution.target: ${quote.execution.target}`);
22
+ console.log(` - approvalAddress: ${quote.approvalAddress || 'MISSING (UNDEFINED)'}`);
23
+ console.log(` - execution.value: ${quote.execution.value.toString()} wei (Should be 0 for ERC20)`);
24
+ if (quote.approvalAddress && quote.approvalAddress.toLowerCase() !== quote.execution.target.toLowerCase()) {
25
+ console.log(` ⚠️ WARNING: execution.target DOES NOT MATCH approvalAddress!`);
26
+ }
27
+ else if (!quote.approvalAddress) {
28
+ console.log(` 🚨 CRITICAL: Provider DID NOT return an approvalAddress!`);
29
+ }
30
+ if (quote.execution.value > 0n) {
31
+ console.log(` 🚨 FATAL EXPLOIT: Provider requested native ETH value > 0 for an ERC20 swap!`);
32
+ }
33
+ }
34
+ catch (err) {
35
+ console.log(`[-] FAILED: ${err.message}`);
36
+ }
37
+ }
38
+ async function main() {
39
+ await providerRegistry_1.aggregatorRegistry.autoDiscover();
40
+ const providers = ['lifi', '0x', 'oneinch', 'kyberswap', 'openocean'];
41
+ for (const p of providers) {
42
+ await testMainnetSwap(p);
43
+ }
44
+ }
45
+ main().catch(console.error);
@@ -0,0 +1,82 @@
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.compressHistory = compressHistory;
7
+ exports.needsCompression = needsCompression;
8
+ /**
9
+ * Context Summarizer — P6: Prevent Context Window Overflow
10
+ *
11
+ * When conversation history grows too long, summarise older messages
12
+ * into a compact paragraph and return a trimmed history that fits
13
+ * within a safe token budget. Mirrors the approach used by Claude/GPT
14
+ * to maintain long-running session coherence.
15
+ */
16
+ const llmUtils_1 = require("./llmUtils");
17
+ const parser_1 = require("../config/parser");
18
+ const picocolors_1 = __importDefault(require("picocolors"));
19
+ /** How many text-only exchanges to keep verbatim before summarising older ones. */
20
+ const VERBATIM_TAIL = 10;
21
+ /** Minimum history length (user+assistant pairs) before we bother summarising. */
22
+ const SUMMARISE_THRESHOLD = 20;
23
+ /**
24
+ * Returns a history array that fits in context.
25
+ * If history is short, returns as-is.
26
+ * If long, prepends a "Conversation Summary" system message and keeps the tail verbatim.
27
+ */
28
+ async function compressHistory(history) {
29
+ const textMessages = history.filter(m => (m.role === 'user' || m.role === 'assistant') && m.content && !m.tool_calls);
30
+ if (textMessages.length < SUMMARISE_THRESHOLD) {
31
+ return history; // nothing to compress yet
32
+ }
33
+ // Split: old messages to summarise, recent tail to keep verbatim
34
+ const tailMessages = textMessages.slice(-VERBATIM_TAIL);
35
+ const oldMessages = textMessages.slice(0, -VERBATIM_TAIL);
36
+ if (oldMessages.length === 0)
37
+ return history;
38
+ try {
39
+ const config = (0, parser_1.loadConfig)();
40
+ const historyText = oldMessages
41
+ .map(m => `${m.role === 'user' ? 'USER' : 'ASSISTANT'}: ${m.content}`)
42
+ .join('\n');
43
+ const summaryRes = await (0, llmUtils_1.executeWithRetry)(async (client) => client.chat({
44
+ model: config.llm.model,
45
+ temperature: 0.1,
46
+ messages: [
47
+ {
48
+ role: 'system',
49
+ content: `You are a conversation summarizer. Summarize the following conversation exchange into a single concise paragraph (max 200 words).
50
+ Focus on: key decisions made, important facts established, user preferences expressed, and task outcomes.
51
+ Write in third person. Be factual, not narrative.`
52
+ },
53
+ { role: 'user', content: historyText }
54
+ ]
55
+ }));
56
+ const summaryText = summaryRes.message?.content?.trim() || '';
57
+ if (!summaryText)
58
+ return history;
59
+ console.log(picocolors_1.default.magenta(`[ContextSummarizer] Compressed ${oldMessages.length} old messages into summary.`));
60
+ // Return: summary as system note + verbatim tail + all tool messages (never drop tool messages)
61
+ const toolMessages = history.filter(m => m.role === 'tool' || (m.role === 'assistant' && m.tool_calls));
62
+ return [
63
+ {
64
+ role: 'system',
65
+ content: `--- CONVERSATION SUMMARY (earlier context) ---\n${summaryText}\n--- END SUMMARY ---`
66
+ },
67
+ ...tailMessages,
68
+ ...toolMessages.slice(-6) // keep last 6 tool interactions
69
+ ];
70
+ }
71
+ catch (e) {
72
+ // On failure, just return the tail — never crash the agent
73
+ return history.slice(-VERBATIM_TAIL * 2);
74
+ }
75
+ }
76
+ /**
77
+ * Fast check — should we attempt compression?
78
+ */
79
+ function needsCompression(history) {
80
+ const textCount = history.filter(m => (m.role === 'user' || m.role === 'assistant') && m.content && !m.tool_calls).length;
81
+ return textCount >= SUMMARISE_THRESHOLD;
82
+ }
@@ -48,7 +48,7 @@ const reverseSkillMapping = {
48
48
  'analyze_market': { category: 'web3', name: 'marketAnalysis' },
49
49
  'get_trending_tokens': { category: 'web3', name: 'getTrendingTokens' },
50
50
  'manage_custom_tokens': { category: 'web3', name: 'manageCustomTokens' },
51
- 'get_price': { category: 'web3', name: 'getPrice' },
51
+ 'get_price_and_fiat_value': { category: 'web3', name: 'getPrice' },
52
52
  'supply_aave': { category: 'web3', name: 'aaveSupply' },
53
53
  'revoke_approval': { category: 'web3', name: 'revokeApproval' },
54
54
  'deposit_yield_vault': { category: 'web3', name: 'vaultDeposit' },
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSmartStreamWrapper = exports.simulateStream = void 0;
4
+ const simulateStream = async (text, onChunk, msPerChunk = 20, charsPerChunk = 3) => {
5
+ return new Promise((resolve) => {
6
+ let index = 0;
7
+ if (!text) {
8
+ resolve();
9
+ return;
10
+ }
11
+ const intervalId = setInterval(() => {
12
+ if (index < text.length) {
13
+ const chunk = text.substring(index, index + charsPerChunk);
14
+ onChunk(chunk);
15
+ index += charsPerChunk;
16
+ }
17
+ else {
18
+ clearInterval(intervalId);
19
+ resolve();
20
+ }
21
+ }, msPerChunk);
22
+ });
23
+ };
24
+ exports.simulateStream = simulateStream;
25
+ /**
26
+ * Creates a smart wrapper around an onChunk callback.
27
+ * If the incoming chunk is large (e.g. Gemini buffering), it intercepts it and streams it smoothly.
28
+ * If the chunk is small (e.g. OpenAI native stream), it passes it instantly.
29
+ */
30
+ const createSmartStreamWrapper = (originalOnChunk) => {
31
+ let isSimulating = false;
32
+ let queue = '';
33
+ let resolveWait = null;
34
+ let waitPromise = Promise.resolve();
35
+ const processQueue = async () => {
36
+ if (isSimulating || queue.length === 0)
37
+ return;
38
+ isSimulating = true;
39
+ // Create a new wait promise if one doesn't exist
40
+ if (!resolveWait) {
41
+ waitPromise = new Promise(r => { resolveWait = r; });
42
+ }
43
+ while (queue.length > 0) {
44
+ const chars = queue.substring(0, 3);
45
+ queue = queue.substring(3);
46
+ originalOnChunk(chars);
47
+ await new Promise(r => setTimeout(r, 20));
48
+ }
49
+ isSimulating = false;
50
+ if (resolveWait) {
51
+ resolveWait();
52
+ resolveWait = null;
53
+ }
54
+ };
55
+ let accumulatedRaw = '';
56
+ let sentLength = 0;
57
+ return {
58
+ onChunk: (chunk) => {
59
+ accumulatedRaw += chunk;
60
+ // Strip any <think> or <thought> block.
61
+ // The (<\/\1>|$) part matches up to the closing tag, or up to the END of the string if it's unclosed.
62
+ const cleanText = accumulatedRaw.replace(/<(think|thought)[\s\S]*?(<\/\1>|$)/gi, '');
63
+ if (cleanText.length > sentLength) {
64
+ const newText = cleanText.substring(sentLength);
65
+ sentLength = cleanText.length;
66
+ if (newText.length > 30) {
67
+ queue += newText;
68
+ processQueue();
69
+ }
70
+ else {
71
+ if (isSimulating) {
72
+ queue += newText;
73
+ }
74
+ else {
75
+ originalOnChunk(newText);
76
+ }
77
+ }
78
+ }
79
+ },
80
+ wait: async () => {
81
+ await waitPromise;
82
+ }
83
+ };
84
+ };
85
+ exports.createSmartStreamWrapper = createSmartStreamWrapper;
@@ -24,7 +24,9 @@ class ArbitrumBridgeProvider {
24
24
  return true;
25
25
  }
26
26
  supports(request) {
27
- if (request.fromChain !== 'sepolia' || request.toChain !== 'arbitrum_sepolia')
27
+ const isL1ToL2 = request.fromChain === 'sepolia' && request.toChain === 'arbitrum_sepolia';
28
+ const isL2ToL1 = request.toChain === 'sepolia' && request.fromChain === 'arbitrum_sepolia';
29
+ if (!isL1ToL2 && !isL2ToL1)
28
30
  return false;
29
31
  const isNative = request.fromToken.toLowerCase() === 'eth' ||
30
32
  request.fromToken.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' ||
@@ -32,27 +34,42 @@ class ArbitrumBridgeProvider {
32
34
  return isNative;
33
35
  }
34
36
  async getQuote(request, context) {
35
- const inboxAddress = '0xaAe29B0366299461418F5324a79Afc425BE5ae21';
36
- const depositEthAbi = (0, viem_1.parseAbi)(['function depositEth() payable returns (uint256)']);
37
- const callData = (0, viem_1.encodeFunctionData)({
38
- abi: depositEthAbi,
39
- functionName: 'depositEth'
40
- });
37
+ const isL1ToL2 = request.fromChain === 'sepolia';
38
+ let targetAddress;
39
+ let callData;
40
+ if (isL1ToL2) {
41
+ targetAddress = '0xaAe29B0366299461418F5324a79Afc425BE5ae21'; // Delayed Inbox
42
+ const depositEthAbi = (0, viem_1.parseAbi)(['function depositEth() payable returns (uint256)']);
43
+ callData = (0, viem_1.encodeFunctionData)({
44
+ abi: depositEthAbi,
45
+ functionName: 'depositEth'
46
+ });
47
+ }
48
+ else {
49
+ targetAddress = '0x0000000000000000000000000000000000000064'; // ArbSys precompile
50
+ const withdrawEthAbi = (0, viem_1.parseAbi)(['function withdrawEth(address destination) payable returns (uint256)']);
51
+ callData = (0, viem_1.encodeFunctionData)({
52
+ abi: withdrawEthAbi,
53
+ functionName: 'withdrawEth',
54
+ args: [request.userAddress]
55
+ });
56
+ }
57
+ const note = isL1ToL2 ? '100% Real L1->L2 Bridge Transaction via Arbitrum Delayed Inbox' : 'Arbitrum ArbSys L2->L1 Withdrawal (Requires ~7 day challenge period)';
41
58
  return {
42
59
  provider: this.manifest.name,
43
60
  routeId: `arb-bridge-${crypto_1.default.randomUUID()}`,
44
- fromChainId: 11155111, // Sepolia
45
- toChainId: 421614, // Arb Sepolia
61
+ fromChainId: isL1ToL2 ? 11155111 : 421614,
62
+ toChainId: isL1ToL2 ? 421614 : 11155111,
46
63
  inputAmount: BigInt(request.amountInWei),
47
64
  outputAmount: BigInt(request.amountInWei), // 1:1 on official bridge
48
65
  executable: true,
49
66
  expiresAt: Date.now() + 86400000, // Valid for a long time as it's a fixed contract call
50
67
  execution: {
51
- target: inboxAddress,
68
+ target: targetAddress,
52
69
  calldata: callData,
53
70
  value: BigInt(request.amountInWei)
54
71
  },
55
- raw: { note: '100% Real L1->L2 Bridge Transaction via Arbitrum Delayed Inbox' }
72
+ raw: { note }
56
73
  };
57
74
  }
58
75
  async isHealthy() {
@@ -24,8 +24,9 @@ class OpBridgeProvider {
24
24
  return true;
25
25
  }
26
26
  supports(request) {
27
- const isOpStack = request.toChain === 'optimism_sepolia' || request.toChain === 'base_sepolia';
28
- if (request.fromChain !== 'sepolia' || !isOpStack)
27
+ const isL1ToL2 = request.fromChain === 'sepolia' && (request.toChain === 'optimism_sepolia' || request.toChain === 'base_sepolia');
28
+ const isL2ToL1 = request.toChain === 'sepolia' && (request.fromChain === 'optimism_sepolia' || request.fromChain === 'base_sepolia');
29
+ if (!isL1ToL2 && !isL2ToL1)
29
30
  return false;
30
31
  const isNative = request.fromToken.toLowerCase() === 'eth' ||
31
32
  request.fromToken.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' ||
@@ -33,34 +34,47 @@ class OpBridgeProvider {
33
34
  return isNative;
34
35
  }
35
36
  async getQuote(request, context) {
36
- // Each OP Stack L2 has its OWN L1StandardBridgeProxy on Sepolia L1
37
- // Using the wrong address sends ETH to the wrong contract = loss of funds
38
- const BRIDGE_ADDRESSES = {
39
- optimism_sepolia: '0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1', // Confirmed: OP Sepolia L1StandardBridgeProxy
40
- base_sepolia: '0xfd0Bf71F60660E2f608ed56e1659C450eB113120', // Confirmed: Base Sepolia L1StandardBridgeProxy
41
- };
42
- const bridgeAddress = BRIDGE_ADDRESSES[request.toChain];
43
- if (!bridgeAddress) {
44
- throw new Error(`[OpBridgeProvider] No bridge address configured for destination chain: ${request.toChain}`);
37
+ const isL1ToL2 = request.fromChain === 'sepolia';
38
+ let bridgeAddress;
39
+ let callData;
40
+ if (isL1ToL2) {
41
+ // L1 to L2
42
+ const BRIDGE_ADDRESSES = {
43
+ optimism_sepolia: '0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1',
44
+ base_sepolia: '0xfd0Bf71F60660E2f608ed56e1659C450eB113120',
45
+ };
46
+ bridgeAddress = BRIDGE_ADDRESSES[request.toChain];
47
+ if (!bridgeAddress) {
48
+ throw new Error(`[OpBridgeProvider] No bridge address configured for destination chain: ${request.toChain}`);
49
+ }
50
+ const depositEthAbi = (0, viem_1.parseAbi)([
51
+ 'function depositETH(uint32 _minGasLimit, bytes _extraData) payable'
52
+ ]);
53
+ callData = (0, viem_1.encodeFunctionData)({
54
+ abi: depositEthAbi,
55
+ functionName: 'depositETH',
56
+ args: [200000, '0x']
57
+ });
58
+ }
59
+ else {
60
+ // L2 to L1
61
+ bridgeAddress = '0x4200000000000000000000000000000000000010'; // L2StandardBridge predeploy on OP Stack
62
+ const bridgeEthAbi = (0, viem_1.parseAbi)([
63
+ 'function bridgeETH(uint32 _minGasLimit, bytes _extraData) payable'
64
+ ]);
65
+ callData = (0, viem_1.encodeFunctionData)({
66
+ abi: bridgeEthAbi,
67
+ functionName: 'bridgeETH',
68
+ args: [200000, '0x']
69
+ });
45
70
  }
46
- // ABI for depositETH
47
- const depositEthAbi = (0, viem_1.parseAbi)([
48
- 'function depositETH(uint32 _minGasLimit, bytes _extraData) payable'
49
- ]);
50
- // OP Stack requires a minGasLimit. 200000 is a safe default for simple ETH transfers.
51
- const minGasLimit = 200000;
52
- const extraData = '0x';
53
- const callData = (0, viem_1.encodeFunctionData)({
54
- abi: depositEthAbi,
55
- functionName: 'depositETH',
56
- args: [minGasLimit, extraData]
57
- });
58
- const destChainId = request.toChain === 'optimism_sepolia' ? 11155420 : 84532;
71
+ const getChainId = (name) => name === 'sepolia' ? 11155111 : (name === 'optimism_sepolia' ? 11155420 : 84532);
72
+ const note = isL1ToL2 ? 'OP Stack Standard Bridge L1->L2' : 'OP Stack Standard Bridge L2->L1 (Requires 7-day challenge period to finalize)';
59
73
  return {
60
74
  provider: this.manifest.name,
61
75
  routeId: `op-bridge-${crypto_1.default.randomUUID()}`,
62
- fromChainId: 11155111,
63
- toChainId: destChainId,
76
+ fromChainId: getChainId(request.fromChain),
77
+ toChainId: getChainId(request.toChain),
64
78
  inputAmount: BigInt(request.amountInWei),
65
79
  outputAmount: BigInt(request.amountInWei), // 1:1 bridging
66
80
  executable: true,
@@ -70,7 +84,7 @@ class OpBridgeProvider {
70
84
  calldata: callData,
71
85
  value: BigInt(request.amountInWei)
72
86
  },
73
- raw: { note: 'OP Stack Standard Bridge L1->L2' }
87
+ raw: { note }
74
88
  };
75
89
  }
76
90
  async isHealthy() {
@@ -0,0 +1,65 @@
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.TestnetSwapProvider = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ class TestnetSwapProvider {
9
+ manifest = {
10
+ id: 'testnet_mock_swap',
11
+ name: 'Testnet Simulated Swap',
12
+ version: '1.0.1',
13
+ networks: ['testnet'],
14
+ capabilities: ['swap'],
15
+ allowedDomains: [],
16
+ permissions: {
17
+ network: false,
18
+ walletAccess: 'none',
19
+ filesystem: 'none'
20
+ }
21
+ };
22
+ isCrossChainSupported() {
23
+ return false;
24
+ }
25
+ supports(request) {
26
+ if (request.fromChain !== request.toChain)
27
+ return false;
28
+ // Only support testnet chains
29
+ return request.fromChain.includes('sepolia');
30
+ }
31
+ async getQuote(request, context) {
32
+ const chainIds = {
33
+ sepolia: 11155111,
34
+ base_sepolia: 84532,
35
+ optimism_sepolia: 11155420,
36
+ arbitrum_sepolia: 421614
37
+ };
38
+ // Simulate 1:0.98 exchange rate for testing (or a fixed amount if amounts aren't known)
39
+ // To make it look realistic, we just output 98% of the input conceptually (not accurate for different decimals, but works for mock UX).
40
+ const outAmount = (BigInt(request.amountInWei) * 98n) / 100n;
41
+ return {
42
+ provider: this.manifest.name,
43
+ routeId: `testnet-swap-${crypto_1.default.randomUUID()}`,
44
+ fromChainId: chainIds[request.fromChain] || 11155111,
45
+ toChainId: chainIds[request.toChain] || 11155111,
46
+ inputAmount: BigInt(request.amountInWei),
47
+ outputAmount: outAmount,
48
+ estimatedGasUsd: 0.05,
49
+ executable: true,
50
+ expiresAt: Date.now() + 86400000,
51
+ execution: {
52
+ // Send a 0 value transaction to the user's own address to simulate contract interaction
53
+ // without actually losing testnet funds or failing.
54
+ target: request.userAddress,
55
+ calldata: '0x',
56
+ value: 0n
57
+ },
58
+ raw: { note: 'Simulated Testnet Swap. Generating a dummy zero-value transaction for UI verification.' }
59
+ };
60
+ }
61
+ async isHealthy() {
62
+ return { ok: true, checkedAt: Date.now() };
63
+ }
64
+ }
65
+ exports.TestnetSwapProvider = TestnetSwapProvider;
@@ -36,7 +36,13 @@ async function fetchBestRoute(request, preference = "best_output") {
36
36
  // 1. Resolve eligible providers
37
37
  let eligibleProviders = providerRegistry_1.aggregatorRegistry.resolveEligibleProviders(request);
38
38
  if (request.preferredProvider && request.preferredProvider !== "auto") {
39
- eligibleProviders = eligibleProviders.filter(p => p.manifest.id === request.preferredProvider);
39
+ const filteredProviders = eligibleProviders.filter(p => p.manifest.id === request.preferredProvider);
40
+ if (filteredProviders.length > 0) {
41
+ eligibleProviders = filteredProviders;
42
+ }
43
+ else {
44
+ console.warn(`[RouteSelector] LLM Hallucinated or requested an ineligible provider: '${request.preferredProvider}'. Falling back to automatic provider routing.`);
45
+ }
40
46
  }
41
47
  if (eligibleProviders.length === 0) {
42
48
  throw new Error('[RouteSelector] No eligible providers found for this route.');
@@ -16,7 +16,7 @@ const confirmPendingTx_1 = require("../skills/confirmPendingTx");
16
16
  class Web3DefiPlugin {
17
17
  name = 'Web3DefiPlugin';
18
18
  description = 'Core DeFi operations including balance checking, portfolio analysis, and token swapping.';
19
- version = '1.0.0';
19
+ version = '1.0.1';
20
20
  tools = [
21
21
  getBalance_1.getBalanceToolDefinition,
22
22
  checkPortfolio_1.checkPortfolioToolDefinition,
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Web3MarketPlugin = void 0;
4
4
  const httpClient_1 = require("../../utils/httpClient");
5
- const riskIntelligence_1 = require("../utils/riskIntelligence");
6
5
  const marketConfigManager_1 = require("../../config/marketConfigManager");
7
6
  async function fetchCexData(symbol) {
8
7
  try {
@@ -96,139 +95,20 @@ async function fetchCexMomentum(symbol, currentP) {
96
95
  }
97
96
  }
98
97
  }
98
+ const marketAnalysis_1 = require("../skills/marketAnalysis");
99
99
  class Web3MarketPlugin {
100
100
  name = 'MarketAnalysis';
101
- version = '1.0.0';
101
+ version = '1.0.1';
102
102
  description = 'Provides deep market intelligence and analysis for Web3 assets.';
103
103
  tools = [
104
- {
105
- type: 'function',
106
- function: {
107
- name: 'analyze_market',
108
- description: 'Analyzes the market health of a token (Price, FDV, TVL, Holders, Momentum) by fetching from CEX, DEX, CoinGecko, and DefiLlama. Returns a full intelligence report.',
109
- parameters: {
110
- type: 'object',
111
- properties: {
112
- tokenAddressOrSymbol: { type: 'string', description: 'The token symbol (e.g. BTC, ETH) or Contract Address.' },
113
- chainName: { type: 'string', description: 'Optional chain name (e.g. ethereum, solana) if searching by address.' }
114
- },
115
- required: ['tokenAddressOrSymbol']
116
- }
117
- }
118
- }
104
+ marketAnalysis_1.marketAnalysisToolDefinition
119
105
  ];
120
106
  handlers = {
121
107
  'analyze_market': async (args, context) => {
122
108
  try {
123
109
  const { chainName, tokenAddressOrSymbol } = args;
124
- if (!tokenAddressOrSymbol)
125
- throw new Error("Token symbol is invalid.");
126
- const cleanInput = String(tokenAddressOrSymbol || "").replace('$', '').toLowerCase();
127
- const isAddress = cleanInput.startsWith('0x') && cleanInput.length === 42;
128
- let officialSymbol = cleanInput.toUpperCase();
129
- let contractAddress = isAddress ? cleanInput : null;
130
- let network = chainName || "UNKNOWN";
131
- let currentPrice = 0;
132
- let mcapUsd = 0;
133
- let liquidityUsd = 0;
134
- let volume24h = 0;
135
- let priceChange24h = 0;
136
- let rsi = null;
137
- let ma50 = null;
138
- let isCexAsset = false;
139
- // PHASE 1
140
- if (isAddress) {
141
- const targetPair = await fetchDexData(cleanInput, true, chainName);
142
- if (targetPair) {
143
- officialSymbol = targetPair.baseToken.symbol;
144
- contractAddress = targetPair.baseToken.address;
145
- network = targetPair.chainId.toUpperCase();
146
- currentPrice = parseFloat(targetPair.priceUsd || "0");
147
- mcapUsd = targetPair.fdv || 0;
148
- liquidityUsd = targetPair.liquidity?.usd || 0;
149
- volume24h = targetPair.volume?.h24 || 0;
150
- priceChange24h = targetPair.priceChange?.h24 || 0;
151
- }
152
- else {
153
- return `[Market Intelligence] Failed to find data for Contract Address ${tokenAddressOrSymbol} on DEX.`;
154
- }
155
- const momentum = await fetchCexMomentum(officialSymbol, currentPrice);
156
- ma50 = momentum.ma50;
157
- rsi = momentum.rsi;
158
- }
159
- else {
160
- const cgData = await fetchCoinGeckoData(officialSymbol);
161
- const cex = await fetchCexData(officialSymbol);
162
- if (cgData || cex) {
163
- isCexAsset = true;
164
- network = `Global CEX/Market`;
165
- currentPrice = cex ? cex.price : (cgData?.price || 0);
166
- volume24h = cgData ? cgData.vol : (cex?.vol || 0);
167
- priceChange24h = cex ? cex.change : (cgData?.change || 0);
168
- mcapUsd = cgData ? cgData.fdv : (volume24h * 10);
169
- liquidityUsd = cgData ? cgData.fdv * 0.1 : (volume24h * 2);
170
- const momentum = await fetchCexMomentum(officialSymbol, currentPrice);
171
- ma50 = momentum.ma50;
172
- rsi = momentum.rsi;
173
- }
174
- else {
175
- const targetPair = await fetchDexData(cleanInput, false, chainName);
176
- if (targetPair) {
177
- officialSymbol = targetPair.baseToken.symbol;
178
- contractAddress = targetPair.baseToken.address;
179
- network = targetPair.chainId.toUpperCase();
180
- currentPrice = parseFloat(targetPair.priceUsd || "0");
181
- mcapUsd = targetPair.fdv || 0;
182
- liquidityUsd = targetPair.liquidity?.usd || 0;
183
- volume24h = targetPair.volume?.h24 || 0;
184
- priceChange24h = targetPair.priceChange?.h24 || 0;
185
- }
186
- else {
187
- return `[Market Intelligence] Failed to find market data for symbol ${officialSymbol} on both CEX and DEX.`;
188
- }
189
- }
190
- }
191
- // PHASE 2
192
- let tvlChange7d = null;
193
- try {
194
- const llamaData = await (0, httpClient_1.safeFetchJson)(`https://api.llama.fi/protocol/${officialSymbol.toLowerCase()}`);
195
- if (llamaData && llamaData.tvl) {
196
- const tvlList = llamaData.tvl;
197
- if (tvlList.length > 7) {
198
- const todayTvl = tvlList[tvlList.length - 1].totalLiquidityUSD;
199
- const weekAgoTvl = tvlList[tvlList.length - 8].totalLiquidityUSD;
200
- if (weekAgoTvl > 0)
201
- tvlChange7d = ((todayTvl - weekAgoTvl) / weekAgoTvl) * 100;
202
- }
203
- }
204
- }
205
- catch { }
206
- // PHASE 3
207
- let top10HoldersPercent = null;
208
- if (contractAddress || isCexAsset) {
209
- if (mcapUsd > 100000000)
210
- top10HoldersPercent = 15;
211
- else if (mcapUsd < 500000)
212
- top10HoldersPercent = 85;
213
- else
214
- top10HoldersPercent = 45;
215
- }
216
- // PHASE 4
217
- const healthResult = (0, riskIntelligence_1.generateMarketHealthReport)(liquidityUsd, mcapUsd, tvlChange7d, volume24h, priceChange24h, top10HoldersPercent, rsi, currentPrice, ma50);
218
- // PHASE 5
219
- let report = `📊 **Market Intelligence Report: ${officialSymbol}**\n`;
220
- report += `CA: \`${contractAddress || 'N/A'}\` | Network: ${network}\n\n`;
221
- report += `**⭐ Overall Market Health Score:** ${healthResult.overallScore} / 10\n\n`;
222
- report += `**1. Liquidity Risk:** ${healthResult.liquidityScore !== null ? healthResult.liquidityScore + '/10' : '[ N/A ]'}\n`;
223
- report += `- Liquidity: $${liquidityUsd.toLocaleString()} vs FDV: $${mcapUsd.toLocaleString()}\n`;
224
- report += `**2. Smart Money Flow:** ${healthResult.smartMoneyScore !== null ? healthResult.smartMoneyScore + '/10' : '[ N/A - Not in DefiLlama ]'}\n`;
225
- report += `- 24h Volume: $${volume24h.toLocaleString()} | TVL 7D Change: ${tvlChange7d !== null ? tvlChange7d.toFixed(2) + '%' : 'N/A'}\n`;
226
- report += `**3. Holder Concentration:** ${healthResult.concentrationScore !== null ? healthResult.concentrationScore + '/10' : '[ N/A - RPC Pending ]'}\n`;
227
- report += `- Top 10 Holders: ${top10HoldersPercent !== null ? top10HoldersPercent + '%' : 'N/A'}\n`;
228
- report += `**4. Momentum (CEX):** ${healthResult.momentumScore !== null ? healthResult.momentumScore + '/10' : '[ N/A - DEX Only Coin ]'}\n`;
229
- report += `- Price: $${currentPrice} | MA50: ${ma50 ? '$' + ma50.toFixed(4) : 'N/A'} | RSI: ${rsi || 'N/A'}\n\n`;
230
- report += `*System Note for LLM: Use this exact data to provide a "Market Summary" and "Suggested Autonomous Actions" in the user's native language. If CEX momentum is N/A, explicitly warn about high risk Degen/Memecoin status. IMPORTANT: Always include a clear disclaimer at the end (translated into the user's native language) stating that this analysis is NOT financial advice (NFA).*`;
231
- return report;
110
+ const { analyzeMarket } = require('../skills/marketAnalysis');
111
+ return await analyzeMarket(chainName, tokenAddressOrSymbol);
232
112
  }
233
113
  catch (error) {
234
114
  return `[Market Intelligence] Failed to aggregate data: ${error.message}`;