nyxora 26.6.30 → 26.7.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.
Files changed (102) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/README.md +14 -2
  3. package/dist/packages/core/src/agent/honchoDaemon.js +91 -0
  4. package/dist/packages/core/src/agent/osAgent.js +82 -60
  5. package/dist/packages/core/src/agent/reasoning.js +25 -14
  6. package/dist/packages/core/src/agent/updateProfile.js +13 -16
  7. package/dist/packages/core/src/agent/web3Agent.js +82 -62
  8. package/dist/packages/core/src/cognitive/cognitiveManager.js +52 -0
  9. package/dist/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +54 -0
  10. package/dist/packages/core/src/config/parser.js +1 -0
  11. package/dist/packages/core/src/config/paths.js +14 -4
  12. package/dist/packages/core/src/gateway/server.js +54 -2
  13. package/dist/packages/core/src/gateway/telegram.js +3 -104
  14. package/dist/packages/core/src/memory/episodic.js +47 -6
  15. package/dist/packages/core/src/memory/promotionEngine.js +4 -1
  16. package/dist/packages/core/src/plugin/PluginManager.js +18 -3
  17. package/dist/packages/core/src/plugin/registry.js +1 -0
  18. package/dist/packages/core/src/system/agentskills.js +184 -0
  19. package/dist/packages/core/src/system/plugins/SystemCorePlugin.js +6 -1
  20. package/dist/packages/core/src/system/plugins/SystemExternalPlugin.js +18 -0
  21. package/dist/packages/core/src/system/plugins/SystemWorkspacePlugin.js +6 -1
  22. package/dist/packages/core/src/system/plugins/createSkill.js +41 -0
  23. package/dist/packages/core/src/system/skillExtractor.js +94 -0
  24. package/dist/packages/core/src/system/skills/createAgentSkill.js +84 -0
  25. package/dist/packages/core/src/system/skills/createCognitiveSkill.js +53 -0
  26. package/dist/packages/core/src/system/skills/forgetMemory.js +38 -0
  27. package/dist/packages/core/src/utils/llmUtils.js +4 -3
  28. package/dist/packages/core/src/utils/skillManager.js +5 -1
  29. package/dist/packages/core/src/web3/plugins/Web3DefiPlugin.js +6 -1
  30. package/dist/packages/core/src/web3/plugins/Web3MarketPlugin.js +239 -0
  31. package/dist/packages/core/src/web3/plugins/Web3SecurityPlugin.js +4 -4
  32. package/dist/packages/core/src/web3/skills/bridgeToken.js +9 -1
  33. package/dist/packages/core/src/web3/skills/checkRegistryStatus.js +1 -1
  34. package/dist/packages/core/src/web3/skills/confirmPendingTx.js +134 -0
  35. package/dist/packages/core/src/web3/skills/customTx.js +44 -1
  36. package/dist/packages/core/src/web3/skills/defiLending.js +43 -3
  37. package/dist/packages/core/src/web3/skills/getBalance.js +1 -1
  38. package/dist/packages/core/src/web3/skills/getTrendingTokens.js +67 -0
  39. package/dist/packages/core/src/web3/skills/mintNft.js +42 -1
  40. package/dist/packages/core/src/web3/skills/provideLiquidity.js +46 -4
  41. package/dist/packages/core/src/web3/skills/revokeApprovals.js +42 -2
  42. package/dist/packages/core/src/web3/skills/swapToken.js +20 -4
  43. package/dist/packages/core/src/web3/skills/transfer.js +47 -2
  44. package/dist/packages/core/src/web3/skills/yieldVault.js +43 -3
  45. package/dist/packages/core/src/web3/utils/balanceChecker.js +59 -0
  46. package/package.json +1 -2
  47. package/packages/core/package.json +1 -1
  48. package/packages/core/src/agent/honchoDaemon.ts +96 -0
  49. package/packages/core/src/agent/osAgent.ts +90 -69
  50. package/packages/core/src/agent/reasoning.ts +28 -14
  51. package/packages/core/src/agent/updateProfile.ts +17 -16
  52. package/packages/core/src/agent/web3Agent.ts +89 -71
  53. package/packages/core/src/cognitive/cognitiveManager.ts +53 -0
  54. package/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +41 -0
  55. package/packages/core/src/cognitive/prompts/software-development/plan.md +15 -0
  56. package/packages/core/src/cognitive/prompts/software-development/systematic-debugging.md +14 -0
  57. package/packages/core/src/cognitive/prompts/software-development/test-driven-development.md +14 -0
  58. package/packages/core/src/config/parser.ts +4 -0
  59. package/packages/core/src/config/paths.ts +13 -4
  60. package/packages/core/src/gateway/server.ts +63 -2
  61. package/packages/core/src/gateway/telegram.ts +3 -95
  62. package/packages/core/src/memory/episodic.ts +52 -6
  63. package/packages/core/src/memory/promotionEngine.ts +5 -1
  64. package/packages/core/src/plugin/PluginManager.ts +21 -3
  65. package/packages/core/src/plugin/registry.ts +2 -0
  66. package/packages/core/src/system/agentskills.ts +175 -0
  67. package/packages/core/src/system/plugins/SystemCorePlugin.ts +6 -1
  68. package/packages/core/src/system/plugins/SystemExternalPlugin.ts +18 -0
  69. package/packages/core/src/system/plugins/SystemWorkspacePlugin.ts +6 -1
  70. package/packages/core/src/system/plugins/createSkill.ts +41 -0
  71. package/packages/core/src/system/skillExtractor.ts +101 -0
  72. package/packages/core/src/system/skills/createAgentSkill.ts +85 -0
  73. package/packages/core/src/system/skills/createCognitiveSkill.ts +50 -0
  74. package/packages/core/src/system/skills/forgetMemory.ts +34 -0
  75. package/packages/core/src/utils/llmUtils.ts +4 -3
  76. package/packages/core/src/utils/skillManager.ts +5 -1
  77. package/packages/core/src/web3/plugins/Web3DefiPlugin.ts +6 -1
  78. package/packages/core/src/web3/plugins/Web3MarketPlugin.ts +231 -0
  79. package/packages/core/src/web3/plugins/Web3SecurityPlugin.ts +4 -4
  80. package/packages/core/src/web3/skills/bridgeToken.ts +12 -2
  81. package/packages/core/src/web3/skills/checkRegistryStatus.ts +1 -1
  82. package/packages/core/src/web3/skills/confirmPendingTx.ts +94 -0
  83. package/packages/core/src/web3/skills/customTx.ts +13 -1
  84. package/packages/core/src/web3/skills/defiLending.ts +11 -3
  85. package/packages/core/src/web3/skills/getBalance.ts +1 -1
  86. package/packages/core/src/web3/skills/getTrendingTokens.ts +89 -0
  87. package/packages/core/src/web3/skills/mintNft.ts +10 -1
  88. package/packages/core/src/web3/skills/provideLiquidity.ts +13 -4
  89. package/packages/core/src/web3/skills/revokeApprovals.ts +9 -2
  90. package/packages/core/src/web3/skills/swapToken.ts +22 -5
  91. package/packages/core/src/web3/skills/transfer.ts +14 -2
  92. package/packages/core/src/web3/skills/yieldVault.ts +11 -3
  93. package/packages/core/src/web3/utils/balanceChecker.ts +68 -0
  94. package/packages/dashboard/dist/assets/index-CSoNa5cx.css +1 -0
  95. package/packages/dashboard/dist/assets/index-DbRWEoSr.js +16 -0
  96. package/packages/dashboard/dist/index.html +2 -2
  97. package/packages/dashboard/package.json +1 -1
  98. package/packages/mcp-server/package.json +1 -1
  99. package/packages/policy/package.json +1 -1
  100. package/packages/signer/package.json +1 -1
  101. package/packages/dashboard/dist/assets/index-Djg8yTDk.js +0 -16
  102. package/packages/dashboard/dist/assets/index-VEis1hNq.css +0 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepashangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [26.7.2]
9
+ ### Orchestrator Architecture & Extensibility
10
+ - **Multi-Turn Agentic Loop**: Radically overhauled the core LLM execution loop in `web3Agent.ts` and `osAgent.ts`. The engines now utilize a robust `while (turnCount < MAX_TURNS)` architecture. This definitively resolves the "lost context" bug where the AI would drop its tool schemas after a single execution turn, granting Nyxora the endurance to execute highly complex, multi-step operations (e.g., directory scanning followed by programmatic file generation) in a single uninterrupted stream.
11
+ - **External Skill Builder (`SystemExternalPlugin`)**: Engineered a completely isolated IoC plugin dedicated solely to third-party integrations. Introduced the `create_agent_skill` tool, enabling the AI to programmatically scaffold new Node.js execution scripts (`execute.ts`) and auto-generate strict YAML frontmatter for `SKILL.md`. This transforms Nyxora into a fully autonomous Agent-Building Platform that can code and register its own tools dynamically without muddying the native OS/Web3 tool ecosystems.
12
+
13
+ ### Cognitive Reasoning & Identity Architecture
14
+ - **Cognitive Reasoning Engine**: Implemented a powerful new Cognitive Skill system that parses user intent and routes them to strict Standard Operating Procedures (SOPs). Added `cognitiveManager.ts` and foundational SOPs for Systematic Debugging, Test-Driven Development (TDD), and Architecture Planning to drastically improve agent output reliability and strictly enforce developer disciplines.
15
+ - **Episodic Memory V2 Architecture**: Completely overhauled the Episodic Memory SQLite database (`episodic.db`) to fix memory duplication and identity conflict issues (e.g., persona overlap).
16
+ - Added a `key_topic` deduplication layer to ensure old conflicting facts are automatically wiped before new ones are saved.
17
+ - Re-routed the `update_profile` AI tool to write directly to SQLite instead of `user.md`, fixing severe overwrite bugs caused by the background Promotion Engine.
18
+ - **`forget_memory` Tool**: Introduced a surgical memory deletion skill. The AI can now autonomously search for and permanently delete specific habits or mistaken persona traits from the SQLite database upon the user's explicit request.
19
+
20
+ ### Architectural Revamps & UI/UX
21
+ - **Settings Dashboard Redesign**: Restructured the Settings interface into a sleek, full-width Master-Detail layout with a dedicated sidebar. Consolidated all advanced configuration menus (Web3 Skills, OS Skills, RPC, DeFi, Oracles) previously scattered across the main navigation directly into this unified command center for a cleaner user experience.
22
+ - **UI & Layout Optimizations**: Fixed restrictive width constraints on configuration panels, allowing them to fluidly span the entire viewport. Eliminated double-scrollbar bugs on embedded skill panels by seamlessly integrating them into the parent container with unified glassmorphism scrollbar styling.
23
+ - **Zero-Latency Conversational Approval**: Completely overhauled the Web3 transaction approval flow.
24
+ - Eradicated all intrusive UI modals (`PendingTransactions.tsx`) from the Dashboard and ripped out `InlineKeyboard` popup logic from the Telegram Gateway.
25
+ - Transactions are now approved organically via text. The AI autonomously interprets conversational cues (e.g., answering "Yes" or "No") and executes the pending on-chain transaction in the background using the new `confirmPendingTx` skill.
26
+ - **Token Efficiency Intact**: Ingeniously maintained the `fastReturnTools` bypass. Transaction preparation strings now output a direct prompt ("*Please reply with 'Yes' to execute, or 'No' to cancel*") instantly, achieving conversational UX without incurring the latency or API cost of generating an LLM prompt for every single transaction queue.
27
+ - **Pre-flight Balance & Gas Security Check**: Engineered a universal `balanceChecker` utility that validates wallet balances across all 9 Web3 transaction skills *before* queuing them.
28
+ - Acts as a smart guardrail similar to Rabby Wallet's UX. It automatically aborts transaction preparations entirely if the user lacks the required ERC20 tokens or if their Native Coin (ETH/BNB) balance is completely depleted (preventing out-of-gas failures).
29
+ - **Human-Readable Error Feedback**: Overhauled the raw error outputs from 18-decimal Wei formats to standard units. The system now dynamically fetches token metadata (decimals and symbols) on-the-fly and applies `formatUnits` to present clean, readable error messages (e.g., *"You need at least 500 USDC"* instead of raw Wei integers), significantly reducing friction for novice users.
30
+
31
+ ## [26.7.1]
32
+ ### Bug Fixes & Optimizations
33
+ - **Native Coin Resolution Mass Remediation**: Fixed a systemic architectural flaw where Web3 transaction modules strictly validated against the Zero Address (`0x00...00`) for native coins (ETH/BNB/MATIC). The codebase now universally intercepts and processes the `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee` pseudo-address generated by aggregators. This stabilizes critical transactional skills including:
34
+ - **DEX Swapping**: Prevents contract decimals parsing crashes during Native to ERC20 swaps (`swapToken.ts`).
35
+ - **Asset Transfers**: Safely bypasses `transfer()` contract calls when sending native coins (`transfer.ts`).
36
+ - **DeFi Lending**: Ensures AAVE dynamically routes to WETH gateways for native deposits (`defiLending.ts`).
37
+ - **Yield Vaults & Liquidity (V3)**: Secures deposit validations and prevents false rejections (`yieldVault.ts`, `provideLiquidity.ts`).
38
+ - **Security Approvals**: Blocks artificial revoke requests on native coins gracefully (`revokeApprovals.ts`).
39
+ - **Balance Queries**: Correctly routes to native balance RPC methods instead of standard ERC20 `balanceOf` (`getBalance.ts`).
40
+
41
+
8
42
  ## [26.6.30]
9
43
  ### UI/UX & Quality of Life
10
44
  - **AI Web Platform Style Empty State**: Overhauled the default chat interface when no messages are present. The dashboard now features a sleek, centered "What's on your mind today?" greeting, automatically repositioning the input bar to the center.
@@ -24,7 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
24
58
 
25
59
  ## [26.6.29]
26
60
  ### Release & Stability
27
- - **Beta Phase**: Nyxora officially enters the stable Beta phase for wider public testing.
61
+ - **Beta Phase (Reverted)**: Nyxora briefly entered the Beta phase here for wider public testing, but the status has since reverted to Alpha in `v26.7.2` to accommodate massive core architectural experiments.
28
62
  - **NPM Publishing Integrity**: Explicitly whitelisted `CHANGELOG.md` within the `package.json` files array to guarantee release notes are synchronized onto the public NPM registry.
29
63
 
30
64
  ## [26.6.28]
package/README.md CHANGED
@@ -2,13 +2,14 @@
2
2
  **Your Personal Web3 Assistant.**
3
3
 
4
4
 
5
- [![Status: Beta](https://img.shields.io/badge/Status-Beta-green.svg)](#)
5
+ [![Status: Alpha](https://img.shields.io/badge/Status-Alpha-orange.svg)](#)
6
6
  [![Built on Base](https://img.shields.io/badge/Built_on-Base-0052FF?style=flat&logo=base&logoColor=white)](https://base.org/)
7
7
  [![MCP Supported](https://img.shields.io/badge/MCP-Supported-blue.svg)](#)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
9
  [![Security: Defense-in-Depth](https://img.shields.io/badge/Security-Defense--in--Depth-blue.svg)](#️-advanced-security-threat-model)
10
10
  [![Execution: Cryptographic Approval](https://img.shields.io/badge/Execution-Cryptographic--Approval-orange.svg)](#️-advanced-security-threat-model)
11
11
  [![Privacy: Local-Only Keys](https://img.shields.io/badge/Privacy-Local--Only--Keys-success.svg)](#️-advanced-security-threat-model)
12
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://makeapullrequest.com)
12
13
 
13
14
  Nyxora is a **secure, non-custodial runtime infrastructure for autonomous onchain agents** built with a robust Monorepo architecture (Node.js & React). Designed for autonomous workflows with a premium Utility-Centric dark-themed UI and strict client-side key isolation.
14
15
 
@@ -94,12 +95,13 @@ It operates under a **Zero-Trust, Defense-in-Depth Cryptographically Bound Human
94
95
  * **System Automation & Full OS Access**: Instruct the agent to read/write local files, run terminal commands, and browse the web natively.
95
96
  * **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.
96
97
  * **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."*
98
+ * **Autonomous Skill Synthesizing (`skillExtractor.ts`)**: Instruct the AI to learn a new workflow, and it will autonomously write the Node.js execution logic and schema, saving it locally as a custom skill following the **`agentskills.io`** standard!
97
99
 
98
100
  ### 🧠 The Masterpiece Memory Architecture
99
101
  * **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.
100
102
  * **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.
103
+ * **Dialectic User Modeling (Honcho Daemon)**: Nyxora continuously runs an asynchronous background daemon that quietly audits your conversational history. It extracts your behavioral traits, trading style, and risk tolerance, saving them securely to `episodic.db` and injecting them dynamically into the AI's reasoning engine.
101
104
  * **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%.
102
- * **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.
103
105
 
104
106
  ### AI & UI Customization
105
107
  * **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.
@@ -213,6 +215,16 @@ By downloading, installing, or using the Nyxora AI Agent, you agree to our assum
213
215
 
214
216
  ---
215
217
 
218
+ ## 🤝 Contributing
219
+
220
+ We welcome community contributions! Whether you want to fix a bug, improve documentation, or build a whole new Web3 Plugin, we'd love to have your help.
221
+
222
+ Nyxora features an extensible **Plugin Architecture** that makes it incredibly easy to add new capabilities (like new DEXs, Oracles, or Chains) without modifying the core reasoning engine.
223
+
224
+ > **📖 [Read the Contribution Guidelines](CONTRIBUTING.md)** to get started!
225
+
226
+ ---
227
+
216
228
  ## 📖 Official Documentation
217
229
 
218
230
  For complete technical deep-dives into our Cryptographic Architecture, please visit our official VitePress Documentation Site!
@@ -0,0 +1,91 @@
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.honchoDaemon = exports.HonchoDaemon = void 0;
7
+ const parser_1 = require("../config/parser");
8
+ const llmUtils_1 = require("../utils/llmUtils");
9
+ const episodic_1 = require("../memory/episodic");
10
+ const reasoning_1 = require("./reasoning");
11
+ const picocolors_1 = __importDefault(require("picocolors"));
12
+ class HonchoDaemon {
13
+ isRunning = false;
14
+ intervalId = null;
15
+ INTERVAL_MS = 60 * 60 * 1000; // Run every hour
16
+ start() {
17
+ if (this.isRunning)
18
+ return;
19
+ this.isRunning = true;
20
+ // Initial run after 5 minutes
21
+ setTimeout(() => this.runAnalysis(), 5 * 60 * 1000);
22
+ // Scheduled runs
23
+ this.intervalId = setInterval(() => {
24
+ this.runAnalysis();
25
+ }, this.INTERVAL_MS);
26
+ console.log(picocolors_1.default.magenta('[Honcho] Dialectic User Modeling daemon started.'));
27
+ }
28
+ stop() {
29
+ if (this.intervalId) {
30
+ clearInterval(this.intervalId);
31
+ }
32
+ this.isRunning = false;
33
+ console.log(picocolors_1.default.magenta('[Honcho] Daemon stopped.'));
34
+ }
35
+ async runAnalysis() {
36
+ console.log(picocolors_1.default.magenta('[Honcho] Running dialectic user modeling...'));
37
+ const sessions = reasoning_1.logger.getSessions();
38
+ if (sessions.length === 0)
39
+ return;
40
+ const allHistory = reasoning_1.logger.getHistory(undefined, 100); // Get recent 100 messages
41
+ if (allHistory.length < 5)
42
+ return; // Not enough context
43
+ const config = (0, parser_1.loadConfig)();
44
+ const prompt = `You are Honcho, Nyxora's background Persona Auditor.
45
+ Your task is to analyze the user's recent chat history and extract long-term persona traits, preferences, or behavioral rules.
46
+ Focus ONLY on facts about the user. (e.g. "User prefers high-risk trades", "User is a developer", "User wants concise answers", "User hates memecoins").
47
+
48
+ Output your findings as a strict JSON array of strings. If nothing new is found, return [].
49
+ Example: ["User avoids Ethereum mainnet due to gas", "User prefers dark mode"]
50
+
51
+ Chat History:
52
+ ${allHistory.map((m) => `[${m.role}] ${m.content}`).join('\n')}
53
+ `;
54
+ try {
55
+ const response = await (0, llmUtils_1.executeWithRetry)(async (client) => {
56
+ return await client.chat({
57
+ model: config.llm.model,
58
+ messages: [{ role: 'system', content: prompt }],
59
+ temperature: 0.1
60
+ });
61
+ });
62
+ let content = response.message.content || '[]';
63
+ // Clean markdown if any
64
+ content = content.replace(/\`\`\`json/g, '').replace(/\`\`\`/g, '').trim();
65
+ let traits = [];
66
+ try {
67
+ const parsed = JSON.parse(content);
68
+ if (Array.isArray(parsed)) {
69
+ traits = parsed;
70
+ }
71
+ else if (parsed.traits && Array.isArray(parsed.traits)) {
72
+ traits = parsed.traits;
73
+ }
74
+ }
75
+ catch (e) {
76
+ console.error(picocolors_1.default.red('[Honcho] Failed to parse JSON traits'), content);
77
+ }
78
+ if (traits.length > 0) {
79
+ traits.forEach(trait => {
80
+ episodic_1.episodicDB.updatePersonaTrait(trait, 0.8, 'honcho');
81
+ console.log(picocolors_1.default.magenta(`[Honcho] Discovered new trait: ${trait}`));
82
+ });
83
+ }
84
+ }
85
+ catch (e) {
86
+ console.error(picocolors_1.default.red(`[Honcho] Analysis failed: ${e.message}`));
87
+ }
88
+ }
89
+ }
90
+ exports.HonchoDaemon = HonchoDaemon;
91
+ exports.honchoDaemon = new HonchoDaemon();
@@ -10,11 +10,36 @@ const logger_1 = require("../memory/logger");
10
10
  const tracker_1 = require("../gateway/tracker");
11
11
  const episodic_1 = require("../memory/episodic");
12
12
  const skillManager_1 = require("../utils/skillManager");
13
+ const cognitiveManager_1 = require("../cognitive/cognitiveManager");
14
+ const EXECUTION_DISCIPLINE = `
15
+ <tool_persistence>
16
+ Use tools whenever they can increase the accuracy, completeness, or factual correctness of your response.
17
+ Do NOT stop early if another tool call would materially improve the result.
18
+ Continue using tools until the task is completely finished and verified.
19
+ </tool_persistence>
20
+
21
+ <mandatory_tool_use>
22
+ NEVER answer the following using only your internal memory — ALWAYS use the relevant tool:
23
+ - Arithmetic, math, calculations
24
+ - System State: OS version, RAM, processes
25
+ - File contents, file sizes
26
+ - Real-world current events
27
+ </mandatory_tool_use>
28
+
29
+ <act_dont_ask>
30
+ When a user's request has a clear, standard interpretation, take immediate ACTION instead of asking for clarification.
31
+ </act_dont_ask>
32
+
33
+ <task_completion>
34
+ The deliverable must be a working artifact backed by real tool output — not just a description or a plan of how you would do it.
35
+ NEVER fabricate, hallucinate, or forge tool outputs.
36
+ </task_completion>
37
+ `;
13
38
  const registry_1 = require("../plugin/registry");
14
39
  const picocolors_1 = __importDefault(require("picocolors"));
15
40
  exports.logger = new logger_1.Logger();
16
41
  const llmUtils_1 = require("../utils/llmUtils");
17
- function getSystemPrompt(context = 'os') {
42
+ function getSystemPrompt(context = 'os', userInput = '') {
18
43
  const config = (0, parser_1.loadConfig)();
19
44
  const currentDateTime = new Date().toLocaleString('en-US');
20
45
  let basePrompt = `You are Nyxora's OS Agent (System & Automation Specialist).
@@ -27,7 +52,15 @@ CRITICAL RULE 1: NEVER expose internal JSON tool calls. Explain the outcome natu
27
52
  CRITICAL RULE 2: STRICT LANGUAGE MATCHING. Reply in the exact same language as the user's LATEST prompt.
28
53
  CRITICAL RULE 3: FILE SYSTEM SAFETY. You are STRICTLY FORBIDDEN from modifying config.yaml, rpc_key.yaml, or policy.yaml using terminal commands like sed or echo.
29
54
  CRITICAL RULE 4: CRON JOBS VS LIMIT ORDERS. Do NOT use schedule_task for price-based trading triggers. Use schedule_task for time-based recurring tasks.
30
- CRITICAL RULE 5: TOOL CONFIDENCE. NEVER fabricate file contents or command outputs.`;
55
+ CRITICAL RULE 5: TOOL CONFIDENCE. NEVER fabricate file contents or command outputs.
56
+
57
+ ${EXECUTION_DISCIPLINE}
58
+ `;
59
+ // Inject Active Cognitive Skills
60
+ const activeSOP = cognitiveManager_1.cognitiveManager.loadActiveCognitiveSkills(userInput);
61
+ if (activeSOP) {
62
+ basePrompt += `\n\n[ACTIVE COGNITIVE SKILLS]\n${activeSOP}\n`;
63
+ }
31
64
  // Inject Episodic Memories
32
65
  try {
33
66
  const recentMemories = episodic_1.episodicDB.getMemories().slice(0, 10);
@@ -56,30 +89,47 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
56
89
  const { sanitizeHistoryForLLM } = require('../utils/historySanitizer');
57
90
  const sanitizedHistory = sanitizeHistoryForLLM(history, activeTools, config.llm.provider);
58
91
  let messages = [
59
- { role: 'system', content: getSystemPrompt('os') },
92
+ { role: 'system', content: getSystemPrompt('os', input) },
60
93
  ...sanitizedHistory
61
94
  ];
62
95
  try {
63
- const response = await (0, llmUtils_1.executeWithRetry)(async (client) => {
64
- return await client.chat({
65
- model: config.llm.model,
66
- temperature: config.llm.temperature,
67
- messages: messages,
68
- tools: activeTools
96
+ let turnCount = 0;
97
+ const MAX_TURNS = 10;
98
+ while (turnCount < MAX_TURNS) {
99
+ turnCount++;
100
+ const currentHistory = exports.logger.getHistory(sessionId);
101
+ const sanitizedHistory = sanitizeHistoryForLLM(currentHistory, activeTools, config.llm.provider);
102
+ const messages = [
103
+ { role: 'system', content: getSystemPrompt('os', input) },
104
+ ...sanitizedHistory
105
+ ];
106
+ const response = await (0, llmUtils_1.executeWithRetry)(async (client) => {
107
+ return await client.chat({
108
+ model: config.llm.model,
109
+ temperature: config.llm.temperature,
110
+ messages: messages,
111
+ tools: activeTools
112
+ });
69
113
  });
70
- });
71
- const responseMessage = response.message;
72
- tracker_1.Tracker.addMessage();
73
- if (response.usage?.total_tokens) {
74
- tracker_1.Tracker.addTokens(response.usage.total_tokens, config.llm.provider);
75
- }
76
- tracker_1.Tracker.addEvent('llm.response', { provider: config.llm.provider, tool_calls: responseMessage.tool_calls?.length || 0 });
77
- exports.logger.addEntry({
78
- role: 'assistant',
79
- content: responseMessage.content || "",
80
- tool_calls: responseMessage.tool_calls,
81
- }, sessionId);
82
- if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {
114
+ const responseMessage = response.message;
115
+ if (turnCount === 1) {
116
+ tracker_1.Tracker.addMessage();
117
+ }
118
+ if (response.usage?.total_tokens) {
119
+ tracker_1.Tracker.addTokens(response.usage.total_tokens, config.llm.provider);
120
+ }
121
+ tracker_1.Tracker.addEvent('llm.response', { provider: config.llm.provider, tool_calls: responseMessage.tool_calls?.length || 0 });
122
+ exports.logger.addEntry({
123
+ role: 'assistant',
124
+ content: responseMessage.content || "",
125
+ tool_calls: responseMessage.tool_calls,
126
+ }, sessionId);
127
+ if (!responseMessage.tool_calls || responseMessage.tool_calls.length === 0) {
128
+ let finalContent = responseMessage.content || "No response generated.";
129
+ finalContent = finalContent.replace(/<(think|thought|thinking|reasoning|analysis|reflection)>[\s\S]*?<\/\1>\n?/gi, '');
130
+ finalContent = finalContent.trim();
131
+ return finalContent;
132
+ }
83
133
  let canFastReturnAll = true;
84
134
  let accumulatedResults = [];
85
135
  // Enabled fastReturnTools to eliminate 2nd LLM latency for transaction popups
@@ -97,7 +147,12 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
97
147
  if (onProgress)
98
148
  onProgress(`_⚡ Running tool: ${toolName}..._`);
99
149
  try {
100
- args = JSON.parse(toolCall.function.arguments);
150
+ let argStr = toolCall.function.arguments;
151
+ // [Auto-Recovery] Fix common LLM JSON errors (e.g. missing closing brace)
152
+ if (argStr && !argStr.trim().endsWith('}')) {
153
+ argStr += '}';
154
+ }
155
+ args = JSON.parse(argStr);
101
156
  }
102
157
  catch (parseError) {
103
158
  console.error(picocolors_1.default.red(`[LLM Validation Error] Invalid JSON arguments for ${toolName}: ${parseError.message}`));
@@ -157,44 +212,11 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
157
212
  exports.logger.addEntry({ role: 'assistant', content: finalContent }, sessionId);
158
213
  return finalContent;
159
214
  }
160
- // Second call to get the final answer after tool execution
161
- const secondSanitized = sanitizeHistoryForLLM(exports.logger.getHistory(sessionId), activeTools, config.llm.provider);
162
- const secondMessages = [
163
- { role: 'system', content: getSystemPrompt('os') },
164
- ...secondSanitized
165
- ];
166
- const secondResponse = await (0, llmUtils_1.executeWithRetry)(async (client) => {
167
- return await client.chat({
168
- model: config.llm.model,
169
- messages: secondMessages,
170
- });
171
- });
172
- if (secondResponse.usage?.total_tokens) {
173
- tracker_1.Tracker.addTokens(secondResponse.usage.total_tokens, config.llm.provider);
174
- }
175
- tracker_1.Tracker.addEvent('llm.final_response', { provider: config.llm.provider });
176
- let finalContent = secondResponse.message.content || "";
177
- // Clean up orphaned <think> blocks that forgot to output </think>
178
- finalContent = finalContent.replace(/<thought>[\s\S]*?<\/thought>\n?/gi, '');
179
- finalContent = finalContent.replace(/<think>[\s\S]*?<\/think>\n?/gi, '');
180
- if (finalContent.includes('<think>')) {
181
- finalContent = finalContent.replace(/<think>[\s\S]*?\n\n/i, '');
182
- finalContent = finalContent.replace(/<think>[\s\S]*$/i, '');
183
- }
184
- finalContent = finalContent.trim();
185
- exports.logger.addEntry({ role: 'assistant', content: finalContent }, sessionId);
186
- return finalContent;
187
- }
188
- let finalContent = responseMessage.content || "No response generated.";
189
- // Clean up orphaned <think> blocks that forgot to output </think>
190
- finalContent = finalContent.replace(/<thought>[\s\S]*?<\/thought>\n?/gi, '');
191
- finalContent = finalContent.replace(/<think>[\s\S]*?<\/think>\n?/gi, '');
192
- if (finalContent.includes('<think>')) {
193
- finalContent = finalContent.replace(/<think>[\s\S]*?\n\n/i, '');
194
- finalContent = finalContent.replace(/<think>[\s\S]*$/i, '');
215
+ // Loop continues, sending tool results in the next turn
195
216
  }
196
- finalContent = finalContent.trim();
197
- return finalContent;
217
+ const maxTurnMsg = "⚠️ Reached maximum interaction limit (10 turns). Please be more specific.";
218
+ exports.logger.addEntry({ role: 'assistant', content: maxTurnMsg }, sessionId);
219
+ return maxTurnMsg;
198
220
  }
199
221
  catch (error) {
200
222
  console.error("LLM Error:", error);
@@ -135,15 +135,25 @@ Do NOT perform any web3 tasks or generic answers until they provide all 4 detail
135
135
  // V3: Inject Personalized Risk Profile
136
136
  try {
137
137
  const profile = exports.logger.getUserProfile();
138
- if (profile) {
138
+ const personas = episodic_1.episodicDB.getPersonas();
139
+ if (profile || personas.length > 0) {
139
140
  basePrompt += `\n\n--- [USER_PERSONA] RISK PROFILE & PREFERENCES ---\n`;
140
- basePrompt += `Risk Level: ${profile.risk_level}\n`;
141
- basePrompt += `Max Slippage Tolerance: ${profile.max_slippage}%\n`;
142
- basePrompt += `Avoid Memecoins: ${profile.avoid_memecoins ? 'YES' : 'NO'}\n`;
143
- if (profile.custom_rules) {
144
- basePrompt += `Custom Rules: ${profile.custom_rules}\n`;
141
+ if (profile) {
142
+ basePrompt += `Risk Level: ${profile.risk_level}\n`;
143
+ basePrompt += `Max Slippage Tolerance: ${profile.max_slippage}%\n`;
144
+ basePrompt += `Avoid Memecoins: ${profile.avoid_memecoins ? 'YES' : 'NO'}\n`;
145
+ if (profile.custom_rules) {
146
+ basePrompt += `Custom Rules: ${profile.custom_rules}\n`;
147
+ }
148
+ basePrompt += `CRITICAL: You MUST adhere to these risk parameters when advising the user or executing tools. If a requested action violates these parameters (e.g., buying a high-risk memecoin when 'Avoid Memecoins' is YES), you MUST warn the user and refuse execution unless they explicitly override.\n`;
149
+ }
150
+ if (personas.length > 0) {
151
+ basePrompt += `\nObserved Traits (Dialectic Modeling):\n`;
152
+ personas.forEach(p => {
153
+ basePrompt += `- ${p.trait} (Confidence: ${(p.confidence * 100).toFixed(0)}%)\n`;
154
+ });
155
+ basePrompt += `Adapt your tone, vocabulary, and suggestions to align with these observed user traits.\n`;
145
156
  }
146
- basePrompt += `CRITICAL: You MUST adhere to these risk parameters when advising the user or executing tools. If a requested action violates these parameters (e.g., buying a high-risk memecoin when 'Avoid Memecoins' is YES), you MUST warn the user and refuse execution unless they explicitly override.\n`;
147
157
  }
148
158
  }
149
159
  catch { }
@@ -161,14 +171,15 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
161
171
  .map(m => ({ role: m.role === 'system' ? 'user' : m.role, content: m.content || "" }));
162
172
  const routerPrompt = `You are Nyxora's Semantic Intent Router. Your job is to classify the user's FINAL message into one of three categories: 'web3', 'os', or 'general'.
163
173
  Rules:
164
- 1. FOCUS ONLY ON THE FINAL MESSAGE. History is only for resolving pronouns (e.g., "buy it").
165
- 2. If the final message involves blockchain, crypto, bridging, swapping, tokens, or wallets, reply 'web3'.
166
- 3. If the final message involves fetching news, web search, weather, email, files, or terminal, reply 'os'.
167
- 4. If it's just casual conversation, reply 'general'.
168
- Reply with EXACTLY ONE WORD.`;
174
+ 1. FOCUS ONLY ON THE FINAL MESSAGE. History is only for context.
175
+ 2. The user may speak in ANY language, including casual slang, idioms, or abbreviations (e.g., 'tf', 'wd', 'buy', 'sell'). Translate their core intent logically.
176
+ 3. If the core intent involves blockchain, crypto, bridging, swapping, trading, sending/receiving, tokens, wallets, or transactions, reply 'web3'.
177
+ 4. If the core intent involves OS automation, web search, weather, emails, files, terminal, or changing AI settings, reply 'os'.
178
+ 5. If it is purely casual conversation, chit-chat, or greetings, reply 'general'.
179
+ Reply with EXACTLY ONE WORD: web3, os, or general.`;
169
180
  const routerMessages = [
170
181
  { role: 'system', content: routerPrompt },
171
- ...textOnlyHistory.slice(-4),
182
+ ...textOnlyHistory.slice(-10),
172
183
  { role: 'user', content: input }
173
184
  ];
174
185
  let context = 'general';
@@ -178,7 +189,7 @@ Reply with EXACTLY ONE WORD.`;
178
189
  model: config.llm.model,
179
190
  messages: routerMessages,
180
191
  temperature: 0.1,
181
- max_tokens: 10
192
+ max_tokens: 1000
182
193
  });
183
194
  }, 3); // 3 retries for transient 503/429 errors
184
195
  let contextResponse = (routerResponse.message.content || 'general').toLowerCase().trim();
@@ -1,28 +1,25 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.updateProfileToolDefinition = void 0;
7
4
  exports.updateProfile = updateProfile;
8
- const fs_1 = __importDefault(require("fs"));
9
- const paths_1 = require("../config/paths");
10
- function updateProfile(content, mode) {
5
+ const episodic_1 = require("../memory/episodic");
6
+ const promotionEngine_1 = require("../memory/promotionEngine");
7
+ async function updateProfile(content, mode) {
11
8
  try {
12
- const userMdPath = (0, paths_1.getPath)('user.md');
13
9
  if (mode === 'replace') {
14
- fs_1.default.writeFileSync(userMdPath, content, 'utf8');
15
- return "Profile replaced successfully. New user.md has been saved.";
10
+ episodic_1.episodicDB.clearAllMemories();
16
11
  }
17
- else {
18
- let existingContent = "";
19
- if (fs_1.default.existsSync(userMdPath)) {
20
- existingContent = fs_1.default.readFileSync(userMdPath, 'utf8');
12
+ const lines = content.split('\n').filter(l => l.trim() !== '');
13
+ for (const line of lines) {
14
+ let cleanLine = line.trim();
15
+ if (cleanLine.startsWith('- '))
16
+ cleanLine = cleanLine.substring(2);
17
+ if (cleanLine) {
18
+ episodic_1.episodicDB.addCandidateFact(cleanLine, 1.0, 'general', 'permanent');
21
19
  }
22
- const newContent = existingContent + "\n" + content;
23
- fs_1.default.writeFileSync(userMdPath, newContent, 'utf8');
24
- return "Profile appended successfully. New instructions added to user.md.";
25
20
  }
21
+ await promotionEngine_1.PromotionEngine.runPromotionAndDecay();
22
+ return "Profile updated successfully in Episodic DB and synchronized to user.md.";
26
23
  }
27
24
  catch (error) {
28
25
  return `Failed to update profile: ${error.message}`;