nyxora 26.7.2 → 26.7.4

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 (192) hide show
  1. package/CHANGELOG.md +112 -47
  2. package/README.md +25 -21
  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 +245 -0
  8. package/dist/packages/core/src/agent/nyxDaemon.js +97 -0
  9. package/dist/packages/core/src/agent/osAgent.js +351 -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/googleAuthModule.js +2 -0
  20. package/dist/packages/core/src/gateway/server.js +58 -9
  21. package/dist/packages/core/src/gateway/setup-ml.js +64 -0
  22. package/dist/packages/core/src/gateway/setup.js +39 -3
  23. package/dist/packages/core/src/gateway/telegram.js +123 -27
  24. package/dist/packages/core/src/memory/episodic.js +58 -3
  25. package/dist/packages/core/src/memory/logger.js +120 -2
  26. package/dist/packages/core/src/memory/promotionEngine.js +18 -5
  27. package/dist/packages/core/src/system/agentskills.js +10 -0
  28. package/dist/packages/core/src/system/plugins/GoogleWorkspacePlugin.js +10 -2
  29. package/dist/packages/core/src/system/plugins/SystemCorePlugin.js +1 -1
  30. package/dist/packages/core/src/system/plugins/SystemExternalPlugin.js +1 -1
  31. package/dist/packages/core/src/system/plugins/SystemPluginInstallerPlugin.js +1 -1
  32. package/dist/packages/core/src/system/plugins/SystemSocialPlugin.js +1 -1
  33. package/dist/packages/core/src/system/plugins/SystemWebPlugin.js +1 -1
  34. package/dist/packages/core/src/system/plugins/SystemWorkspacePlugin.js +3 -3
  35. package/dist/packages/core/src/system/plugins/createSkill.js +1 -1
  36. package/dist/packages/core/src/system/skillExtractor.js +16 -5
  37. package/dist/packages/core/src/system/skills/executeShell.js +31 -4
  38. package/dist/packages/core/src/system/skills/forgetMemory.js +6 -4
  39. package/dist/packages/core/src/system/skills/googleWorkspace.js +106 -1
  40. package/dist/packages/core/src/system/skills/scheduleTask.js +7 -2
  41. package/dist/packages/core/src/system/skills/searchWeb.js +13 -6
  42. package/dist/packages/core/src/test_mainnet.js +45 -0
  43. package/dist/packages/core/src/utils/contextSummarizer.js +82 -0
  44. package/dist/packages/core/src/utils/skillManager.js +1 -1
  45. package/dist/packages/core/src/utils/streamSimulator.js +85 -0
  46. package/dist/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.js +28 -11
  47. package/dist/packages/core/src/web3/aggregator/providers/OpBridgeProvider.js +41 -27
  48. package/dist/packages/core/src/web3/aggregator/providers/TestnetSwapProvider.js +65 -0
  49. package/dist/packages/core/src/web3/aggregator/routeSelector.js +7 -1
  50. package/dist/packages/core/src/web3/plugins/Web3DefiPlugin.js +1 -1
  51. package/dist/packages/core/src/web3/plugins/Web3MarketPlugin.js +5 -125
  52. package/dist/packages/core/src/web3/plugins/Web3SecurityPlugin.js +1 -1
  53. package/dist/packages/core/src/web3/plugins/Web3WalletPlugin.js +1 -1
  54. package/dist/packages/core/src/web3/skills/bridgeToken.js +19 -4
  55. package/dist/packages/core/src/web3/skills/checkAddress.js +2 -0
  56. package/dist/packages/core/src/web3/skills/checkPortfolio.js +22 -2
  57. package/dist/packages/core/src/web3/skills/checkSecurity.js +2 -0
  58. package/dist/packages/core/src/web3/skills/confirmPendingTx.js +1 -1
  59. package/dist/packages/core/src/web3/skills/createLimitOrder.js +15 -1
  60. package/dist/packages/core/src/web3/skills/customTx.js +3 -0
  61. package/dist/packages/core/src/web3/skills/defiLending.js +2 -0
  62. package/dist/packages/core/src/web3/skills/getBalance.js +2 -0
  63. package/dist/packages/core/src/web3/skills/getPrice.js +134 -27
  64. package/dist/packages/core/src/web3/skills/getTxHistory.js +2 -0
  65. package/dist/packages/core/src/web3/skills/marketAnalysis.js +28 -191
  66. package/dist/packages/core/src/web3/skills/mintNft.js +3 -0
  67. package/dist/packages/core/src/web3/skills/provideLiquidity.js +16 -12
  68. package/dist/packages/core/src/web3/skills/revokeApprovals.js +2 -0
  69. package/dist/packages/core/src/web3/skills/swapToken.js +20 -2
  70. package/dist/packages/core/src/web3/skills/transfer.js +2 -0
  71. package/dist/packages/core/src/web3/skills/yieldVault.js +2 -0
  72. package/dist/packages/core/src/web3/utils/chains.js +19 -0
  73. package/dist/packages/core/src/web3/utils/marketEngine.js +26 -33
  74. package/dist/packages/signer/src/NyxoraSigner.js +181 -0
  75. package/dist/packages/signer/src/index.js +17 -0
  76. package/dist/packages/signer/src/server.js +25 -161
  77. package/launcher.ts +38 -9
  78. package/package.json +8 -3
  79. package/packages/core/package.json +21 -10
  80. package/packages/core/src/agent/bridgeWatcher.ts +3 -2
  81. package/packages/core/src/agent/cronManager.ts +2 -2
  82. package/packages/core/src/agent/llmProvider.ts +221 -0
  83. package/packages/core/src/agent/nyxDaemon.ts +104 -0
  84. package/packages/core/src/agent/osAgent.ts +381 -32
  85. package/packages/core/src/agent/reasoning.ts +376 -64
  86. package/packages/core/src/agent/reasoningScratchpad.ts +45 -0
  87. package/packages/core/src/agent/transactionManager.ts +36 -28
  88. package/packages/core/src/agent/web3Agent.ts +291 -40
  89. package/packages/core/src/cognitive/cognitiveManager.ts +65 -10
  90. package/packages/core/src/cognitive/prompts/web3/market-analysis.md +24 -0
  91. package/packages/core/src/cognitive/prompts/web3/portfolio-review.md +29 -0
  92. package/packages/core/src/cognitive/prompts/web3/risk-assessment.md +28 -0
  93. package/packages/core/src/cognitive/prompts/web3/trade-planning.md +30 -0
  94. package/packages/core/src/config/parser.ts +15 -4
  95. package/packages/core/src/gateway/chat.ts +57 -15
  96. package/packages/core/src/gateway/cli.ts +4 -0
  97. package/packages/core/src/gateway/discordAdapter.ts +87 -0
  98. package/packages/core/src/gateway/googleAuthModule.ts +2 -0
  99. package/packages/core/src/gateway/server.ts +66 -10
  100. package/packages/core/src/gateway/setup-ml.ts +68 -0
  101. package/packages/core/src/gateway/setup.ts +41 -3
  102. package/packages/core/src/gateway/telegram.ts +141 -30
  103. package/packages/core/src/memory/episodic.ts +76 -3
  104. package/packages/core/src/memory/logger.ts +142 -2
  105. package/packages/core/src/memory/promotionEngine.ts +19 -5
  106. package/packages/core/src/system/agentskills.ts +10 -0
  107. package/packages/core/src/system/plugins/GoogleWorkspacePlugin.ts +15 -3
  108. package/packages/core/src/system/plugins/SystemCorePlugin.ts +1 -1
  109. package/packages/core/src/system/plugins/SystemExternalPlugin.ts +1 -1
  110. package/packages/core/src/system/plugins/SystemPluginInstallerPlugin.ts +1 -1
  111. package/packages/core/src/system/plugins/SystemSocialPlugin.ts +1 -1
  112. package/packages/core/src/system/plugins/SystemWebPlugin.ts +1 -1
  113. package/packages/core/src/system/plugins/SystemWorkspacePlugin.ts +3 -3
  114. package/packages/core/src/system/plugins/createSkill.ts +1 -1
  115. package/packages/core/src/system/skillExtractor.ts +16 -5
  116. package/packages/core/src/system/skills/executeShell.ts +38 -7
  117. package/packages/core/src/system/skills/forgetMemory.ts +7 -4
  118. package/packages/core/src/system/skills/googleWorkspace.ts +109 -0
  119. package/packages/core/src/system/skills/scheduleTask.ts +7 -2
  120. package/packages/core/src/system/skills/searchWeb.ts +12 -6
  121. package/packages/core/src/utils/contextSummarizer.ts +100 -0
  122. package/packages/core/src/utils/skillManager.ts +1 -1
  123. package/packages/core/src/utils/streamSimulator.ts +88 -0
  124. package/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.ts +30 -11
  125. package/packages/core/src/web3/aggregator/providers/OpBridgeProvider.ts +43 -29
  126. package/packages/core/src/web3/aggregator/routeSelector.ts +6 -1
  127. package/packages/core/src/web3/plugins/Web3DefiPlugin.ts +1 -1
  128. package/packages/core/src/web3/plugins/Web3MarketPlugin.ts +6 -125
  129. package/packages/core/src/web3/plugins/Web3SecurityPlugin.ts +1 -1
  130. package/packages/core/src/web3/plugins/Web3WalletPlugin.ts +1 -1
  131. package/packages/core/src/web3/skills/bridgeToken.ts +21 -7
  132. package/packages/core/src/web3/skills/checkAddress.ts +2 -0
  133. package/packages/core/src/web3/skills/checkPortfolio.ts +23 -2
  134. package/packages/core/src/web3/skills/checkSecurity.ts +2 -0
  135. package/packages/core/src/web3/skills/confirmPendingTx.ts +1 -1
  136. package/packages/core/src/web3/skills/createLimitOrder.ts +17 -2
  137. package/packages/core/src/web3/skills/customTx.ts +3 -0
  138. package/packages/core/src/web3/skills/defiLending.ts +2 -0
  139. package/packages/core/src/web3/skills/getBalance.ts +2 -0
  140. package/packages/core/src/web3/skills/getPrice.ts +134 -30
  141. package/packages/core/src/web3/skills/getTxHistory.ts +2 -0
  142. package/packages/core/src/web3/skills/marketAnalysis.ts +45 -188
  143. package/packages/core/src/web3/skills/mintNft.ts +3 -0
  144. package/packages/core/src/web3/skills/provideLiquidity.ts +16 -10
  145. package/packages/core/src/web3/skills/revokeApprovals.ts +2 -0
  146. package/packages/core/src/web3/skills/swapToken.ts +20 -3
  147. package/packages/core/src/web3/skills/transfer.ts +2 -0
  148. package/packages/core/src/web3/skills/yieldVault.ts +2 -0
  149. package/packages/core/src/web3/utils/chains.ts +12 -0
  150. package/packages/core/src/web3/utils/marketEngine.ts +27 -33
  151. package/packages/dashboard/dist/assets/index-Czxksiao.js +18 -0
  152. package/packages/dashboard/dist/assets/index-DK2sTU47.css +1 -0
  153. package/packages/dashboard/dist/index.html +2 -2
  154. package/packages/dashboard/package.json +10 -10
  155. package/packages/mcp-server/dist/server.js +5 -1
  156. package/packages/mcp-server/package.json +6 -6
  157. package/packages/mcp-server/src/server.ts +11 -7
  158. package/packages/ml-engine/__pycache__/config.cpython-313.pyc +0 -0
  159. package/packages/ml-engine/__pycache__/main.cpython-313.pyc +0 -0
  160. package/packages/ml-engine/config.py +59 -0
  161. package/packages/ml-engine/main.py +34 -0
  162. package/packages/ml-engine/requirements.txt +22 -0
  163. package/packages/ml-engine/routers/__init__.py +1 -0
  164. package/packages/ml-engine/routers/__pycache__/__init__.cpython-313.pyc +0 -0
  165. package/packages/ml-engine/routers/__pycache__/cognitive.cpython-313.pyc +0 -0
  166. package/packages/ml-engine/routers/__pycache__/critic.cpython-313.pyc +0 -0
  167. package/packages/ml-engine/routers/__pycache__/llm.cpython-313.pyc +0 -0
  168. package/packages/ml-engine/routers/__pycache__/market.cpython-313.pyc +0 -0
  169. package/packages/ml-engine/routers/__pycache__/memory.cpython-313.pyc +0 -0
  170. package/packages/ml-engine/routers/cognitive.py +98 -0
  171. package/packages/ml-engine/routers/critic.py +111 -0
  172. package/packages/ml-engine/routers/llm.py +38 -0
  173. package/packages/ml-engine/routers/market.py +332 -0
  174. package/packages/ml-engine/routers/memory.py +125 -0
  175. package/packages/policy/package.json +3 -3
  176. package/packages/signer/package.json +16 -6
  177. package/packages/signer/src/NyxoraSigner.ts +161 -0
  178. package/packages/signer/src/index.ts +1 -0
  179. package/packages/signer/src/server.ts +25 -135
  180. package/dist/packages/core/src/agent/honchoDaemon.js +0 -91
  181. package/dist/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -54
  182. package/dist/packages/core/src/gateway/test.js +0 -15
  183. package/dist/packages/core/src/web3/Web3DefiPlugin.js +0 -28
  184. package/dist/packages/core/src/web3/aggregator/aggregatorMainnet.js +0 -260
  185. package/dist/packages/core/src/web3/aggregator/aggregatorTestnet.js +0 -119
  186. package/dist/packages/core/src/web3/skills/nativeOpBridge.js +0 -71
  187. package/packages/core/src/agent/honchoDaemon.ts +0 -96
  188. package/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -41
  189. package/packages/core/src/plugin/registry.test.ts +0 -46
  190. package/packages/core/src/utils/formatter.test.ts +0 -41
  191. package/packages/dashboard/dist/assets/index-CSoNa5cx.css +0 -1
  192. package/packages/dashboard/dist/assets/index-DbRWEoSr.js +0 -16
@@ -5,12 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.logger = void 0;
7
7
  exports.processOsIntent = processOsIntent;
8
+ exports.processOsIntentStream = processOsIntentStream;
9
+ const fs_1 = __importDefault(require("fs"));
8
10
  const parser_1 = require("../config/parser");
9
11
  const logger_1 = require("../memory/logger");
10
12
  const tracker_1 = require("../gateway/tracker");
11
13
  const episodic_1 = require("../memory/episodic");
12
14
  const skillManager_1 = require("../utils/skillManager");
13
15
  const cognitiveManager_1 = require("../cognitive/cognitiveManager");
16
+ const reasoningScratchpad_1 = require("./reasoningScratchpad");
17
+ const contextSummarizer_1 = require("../utils/contextSummarizer");
14
18
  const EXECUTION_DISCIPLINE = `
15
19
  <tool_persistence>
16
20
  Use tools whenever they can increase the accuracy, completeness, or factual correctness of your response.
@@ -26,34 +30,73 @@ NEVER answer the following using only your internal memory — ALWAYS use the re
26
30
  - Real-world current events
27
31
  </mandatory_tool_use>
28
32
 
33
+ <web_search_accuracy>
34
+ When using the search_web tool to look up news, current events, or factual data:
35
+ 1. NEVER pass casual, conversational, or highly localized queries directly to the tool (e.g. do not pass "hasil piala dunia tadi pagi").
36
+ 2. ALWAYS translate and optimize the query into an absolute, highly specific, and globally-understood English search query (e.g. "World Cup 2026 match results June 25 2026").
37
+ 3. Use depth: 2 (deep research) for anything that requires high factual accuracy, such as sports scores, news, or complex topics.
38
+ </web_search_accuracy>
39
+
29
40
  <act_dont_ask>
30
41
  When a user's request has a clear, standard interpretation, take immediate ACTION instead of asking for clarification.
42
+ NEVER show a command as a markdown code block and wait. CALL the tool directly.
43
+ NEVER ask "do you want me to run this?" — just run it.
44
+ NEVER say "you need to run this yourself" — you have direct shell access.
45
+ If a command requires sudo and may need a password, just run it and report what happens.
46
+ Only report failure AFTER actually attempting the tool call and receiving an error.
31
47
  </act_dont_ask>
32
48
 
49
+ <anti_hallucination_execution>
50
+ CRITICAL: It is STRICTLY FORBIDDEN to write a bash/shell command in a markdown code block (e.g. \`\`\`bash ... \`\`\`) as a substitute for calling the run_terminal_command tool.
51
+ Writing a code block does NOT execute anything. It is a lie to the user.
52
+ If you write \`\`\`bash\nsudo apt install steam\n\`\`\` instead of calling run_terminal_command, you are hallucinating execution.
53
+ The ONLY way to run a command is to emit a proper tool_call for run_terminal_command.
54
+ If the tool is available, USE IT. Do not simulate or describe running it.
55
+ </anti_hallucination_execution>
56
+
33
57
  <task_completion>
34
58
  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
59
  NEVER fabricate, hallucinate, or forge tool outputs.
36
60
  </task_completion>
61
+
62
+ <self_correction>
63
+ Before providing a final answer to the user (especially regarding dates, events, news, or factual data), you MUST evaluate your tool results inside a <think> block.
64
+ Ask yourself: "Is my answer based on absolute facts, or circumstantial evidence (e.g., guessing a registration date based on a video upload date)?"
65
+ If the evidence is circumstantial or incomplete, you MUST NOT answer the user. Instead, call the search_web tool again with a highly optimized query and depth=2.
66
+ </self_correction>
37
67
  `;
38
68
  const registry_1 = require("../plugin/registry");
69
+ const paths_1 = require("../config/paths");
39
70
  const picocolors_1 = __importDefault(require("picocolors"));
40
71
  exports.logger = new logger_1.Logger();
41
72
  const llmUtils_1 = require("../utils/llmUtils");
42
- function getSystemPrompt(context = 'os', userInput = '') {
73
+ async function getSystemPrompt(context = 'os', userInput = '') {
43
74
  const config = (0, parser_1.loadConfig)();
44
75
  const currentDateTime = new Date().toLocaleString('en-US');
45
76
  let basePrompt = `You are Nyxora's OS Agent (System & Automation Specialist).
46
77
  The current real-world date and time is: ${currentDateTime}.
47
78
 
79
+ You are running LOCALLY on the user's own computer — NOT on a remote cloud server. The 'run_terminal_command' tool executes shell commands directly on this machine, the same physical machine the user is sitting at. You have FULL local shell access. When asked to install software, manage files, or perform any OS task, you MUST use run_terminal_command immediately. NEVER claim you cannot access the user's system.
80
+
48
81
  Reason internally. Never reveal private reasoning. Provide only concise conclusions, assumptions, and actionable steps.
49
82
 
50
83
  [OS EXECUTION WORKFLOW]
51
84
  CRITICAL RULE 1: NEVER expose internal JSON tool calls. Explain the outcome naturally.
52
- CRITICAL RULE 2: STRICT LANGUAGE MATCHING. Reply in the exact same language as the user's LATEST prompt.
85
+ CRITICAL RULE 2: STRICT LANGUAGE MATCHING. Reply in the exact same language as the user's LATEST prompt, UNLESS the Episodic Memories or Cognitive Skills specify a strict language preference.
53
86
  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.
54
87
  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.
55
88
  CRITICAL RULE 5: TOOL CONFIDENCE. NEVER fabricate file contents or command outputs.
56
89
 
90
+ [SUDO & PACKAGE INSTALL STRATEGY]
91
+ This tool runs in a NON-INTERACTIVE shell (no TTY). Therefore:
92
+ - ALWAYS prefix apt/apt-get commands with: DEBIAN_FRONTEND=noninteractive
93
+ - ALWAYS use the -y flag for package installations to auto-confirm.
94
+ - If a command fails with "sudo: a password is required" or similar, DO NOT promise to retry without actually retrying. Instead:
95
+ 1. First retry with: echo 'USER_PASSWORD' | sudo -S <command> — but since you don't know the password, skip this.
96
+ 2. Instead, try running the command WITHOUT sudo if possible (e.g. for user-space tools).
97
+ 3. If sudo is truly required and unavailable, clearly tell the user EXACTLY what command to run manually in their terminal, with a copy-paste ready command. Do not just say it failed without providing a solution.
98
+ - NEVER promise to retry ("let me try again", "I'll run it again", etc.) without immediately making another tool_call in the same response.
99
+
57
100
  ${EXECUTION_DISCIPLINE}
58
101
  `;
59
102
  // Inject Active Cognitive Skills
@@ -61,46 +104,108 @@ ${EXECUTION_DISCIPLINE}
61
104
  if (activeSOP) {
62
105
  basePrompt += `\n\n[ACTIVE COGNITIVE SKILLS]\n${activeSOP}\n`;
63
106
  }
64
- // Inject Episodic Memories
107
+ // Inject Episodic Memories via Python RAG
65
108
  try {
66
- const recentMemories = episodic_1.episodicDB.getMemories().slice(0, 10);
67
- if (recentMemories.length > 0) {
68
- basePrompt += `
69
-
70
- --- EPISODIC MEMORIES (SMART SUGGESTIONS) ---
71
- `;
72
- recentMemories.forEach(mem => {
73
- basePrompt += `- [${mem.category.toUpperCase()}] ${mem.fact} (Confidence: ${(mem.confidence * 100).toFixed(0)}%)
74
- `;
109
+ const ragRes = await fetch('http://127.0.0.1:8000/memory/rag', {
110
+ method: 'POST',
111
+ headers: { 'Content-Type': 'application/json' },
112
+ body: JSON.stringify({ query: userInput, top_k: 5 })
113
+ });
114
+ if (ragRes.ok) {
115
+ const ragData = await ragRes.json();
116
+ if (ragData.memories && ragData.memories.length > 0) {
117
+ basePrompt += `\n\n--- EPISODIC MEMORIES (SMART SUGGESTIONS) ---\n`;
118
+ ragData.memories.forEach((mem) => {
119
+ basePrompt += `- ${mem}\n`;
120
+ });
121
+ }
122
+ }
123
+ }
124
+ catch (e) {
125
+ // Fallback or ignore if Python ML engine is down
126
+ }
127
+ // Inject User Information & Personas from user.md
128
+ try {
129
+ const userMdPath = (0, paths_1.getPath)('user.md');
130
+ if (fs_1.default.existsSync(userMdPath)) {
131
+ const userInstructions = fs_1.default.readFileSync(userMdPath, 'utf8');
132
+ basePrompt += `\n\n--- USER INFORMATION & PREFERENCES ---\n${userInstructions}\n`;
133
+ }
134
+ }
135
+ catch (e) {
136
+ // Ignore error
137
+ }
138
+ // HIGHEST PRIORITY: Inject observed user communication style (NyxDaemon)
139
+ try {
140
+ const strongPersonas = episodic_1.episodicDB.getStrongPersonas(0.5);
141
+ if (strongPersonas.length > 0) {
142
+ basePrompt += `\n\n--- ⚡ OVERRIDE: USER COMMUNICATION STYLE (HIGHEST PRIORITY — OVERRIDES ALL RULES ABOVE) ---\n`;
143
+ basePrompt += `CRITICAL: These are CONFIRMED user preferences observed across multiple conversations. You MUST apply them IMMEDIATELY and CONSISTENTLY, overriding any default tone or style instructions above.\n\n`;
144
+ strongPersonas.forEach(p => {
145
+ const label = p.category ? `[${p.category.toUpperCase()}]` : '[PREFERENCE]';
146
+ basePrompt += `${label} ${p.trait}\n`;
75
147
  });
76
148
  }
77
149
  }
78
- catch { }
150
+ catch (e) {
151
+ // Ignore
152
+ }
79
153
  return basePrompt;
80
154
  }
81
155
  async function processOsIntent(input, role = 'user', onProgress, sessionId) {
82
156
  const config = (0, parser_1.loadConfig)();
83
157
  // Add input to memory
84
158
  exports.logger.addEntry({ role, content: input }, sessionId);
85
- const history = exports.logger.getHistory(sessionId);
86
- // Format messages for OpenAI
159
+ // --- MULTILINGUAL USER CORRECTION DETECTION ---
160
+ const correctionSignals = [
161
+ // ID
162
+ 'salah', 'ngawur', 'keliru', 'bukan', 'tidak benar', 'perbaiki', 'coba lagi',
163
+ // EN
164
+ 'wrong', 'incorrect', 'mistake', 'not right', 'false', 'bad', 'fix', 'try again',
165
+ // ES & FR
166
+ 'incorrecto', 'mal', 'equivocado', 'error', 'falso', 'faux', 'erreur', 'mauvais',
167
+ // DE & RU
168
+ 'falsch', 'inkorrekt', 'fehler', 'ошибка', 'неправильно', 'неверно',
169
+ // JP & ZH
170
+ '違う', '間違い', 'やり直して', '错误', '不对'
171
+ ];
172
+ if (role === 'user' && correctionSignals.some(s => input.toLowerCase().includes(s))) {
173
+ exports.logger.addEntry({
174
+ role: 'system',
175
+ content: `[USER CORRECTION DETECTED] The user indicated your previous answer was WRONG, STALE, or INACCURATE.
176
+ CRITICAL INSTRUCTIONS:
177
+ 1. Do NOT just apologize and repeat the same data from your memory.
178
+ 2. The data in your training memory or previous tool calls is likely stale/incorrect.
179
+ 3. You MUST call a tool (like search_web or others) NOW to verify the facts with FRESH data.
180
+ 4. Base your new answer strictly on the NEW tool results.`
181
+ }, sessionId);
182
+ }
87
183
  let activeTools = [...registry_1.pluginManager.getAllToolDefinitions()];
88
184
  activeTools = activeTools.filter(t => (0, skillManager_1.isSkillActive)(t.function.name));
185
+ // P1: Init reasoning scratchpad for this request
186
+ const scratchpad = new reasoningScratchpad_1.ReasoningScratchpad();
187
+ // P3: Build system prompt ONCE per request — not per turn
188
+ const cachedSystemPrompt = await getSystemPrompt('os', input);
89
189
  const { sanitizeHistoryForLLM } = require('../utils/historySanitizer');
90
- const sanitizedHistory = sanitizeHistoryForLLM(history, activeTools, config.llm.provider);
91
- let messages = [
92
- { role: 'system', content: getSystemPrompt('os', input) },
93
- ...sanitizedHistory
94
- ];
95
190
  try {
96
191
  let turnCount = 0;
97
192
  const MAX_TURNS = 10;
193
+ let consecutiveToolErrors = 0;
194
+ let criticHasFired = false; // Critic Pass hanya aktif 1x per request
98
195
  while (turnCount < MAX_TURNS) {
99
196
  turnCount++;
100
197
  const currentHistory = exports.logger.getHistory(sessionId);
101
- const sanitizedHistory = sanitizeHistoryForLLM(currentHistory, activeTools, config.llm.provider);
198
+ // P6: Compress history if conversation is too long
199
+ const historyToUse = (0, contextSummarizer_1.needsCompression)(currentHistory)
200
+ ? await (0, contextSummarizer_1.compressHistory)(currentHistory)
201
+ : currentHistory;
202
+ const sanitizedHistory = sanitizeHistoryForLLM(historyToUse, activeTools, config.llm.provider);
203
+ // P1: Inject scratchpad into system prompt for turns > 1
204
+ const sysPrompt = turnCount === 1
205
+ ? cachedSystemPrompt
206
+ : cachedSystemPrompt + scratchpad.getInjection();
102
207
  const messages = [
103
- { role: 'system', content: getSystemPrompt('os', input) },
208
+ { role: 'system', content: sysPrompt },
104
209
  ...sanitizedHistory
105
210
  ];
106
211
  const response = await (0, llmUtils_1.executeWithRetry)(async (client) => {
@@ -119,16 +224,45 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
119
224
  tracker_1.Tracker.addTokens(response.usage.total_tokens, config.llm.provider);
120
225
  }
121
226
  tracker_1.Tracker.addEvent('llm.response', { provider: config.llm.provider, tool_calls: responseMessage.tool_calls?.length || 0 });
227
+ // P1: Capture <think> blocks for scratchpad, get clean content
228
+ const cleanedContent = scratchpad.capture(responseMessage.content || '', turnCount);
122
229
  exports.logger.addEntry({
123
230
  role: 'assistant',
124
- content: responseMessage.content || "",
231
+ content: cleanedContent || '',
125
232
  tool_calls: responseMessage.tool_calls,
126
233
  }, sessionId);
127
234
  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;
235
+ // --- CRITIC PASS (Self-Improvement) ---
236
+ const isLongResponse = (cleanedContent?.length ?? 0) > 100;
237
+ if (isLongResponse && !criticHasFired) {
238
+ criticHasFired = true;
239
+ try {
240
+ const criticRes = await fetch('http://127.0.0.1:8000/cognitive/critic', {
241
+ method: 'POST',
242
+ headers: { 'Content-Type': 'application/json' },
243
+ body: JSON.stringify({ user_input: input, draft_answer: cleanedContent, current_utc_datetime: new Date().toISOString() })
244
+ });
245
+ if (criticRes.ok) {
246
+ const evaluation = await criticRes.json();
247
+ if (evaluation.needs_revision) {
248
+ console.log(picocolors_1.default.cyan(`[🧠 Critic] Revision needed. Confidence: ${evaluation.factual_confidence?.toFixed(2)}. Completeness: ${evaluation.completeness?.toFixed(2)}. Re-generating...`));
249
+ exports.logger.addEntry({
250
+ role: 'system',
251
+ content: `[SELF-CRITIQUE — MANDATORY REVISION] Your previous answer was REJECTED. Issues:\n${evaluation.revision_instructions}\n\nCRITICAL REVISION RULES:\n1. Look at the tool results (search_web, etc.) ALREADY in this conversation history above.\n2. Base your revised answer EXCLUSIVELY on those tool results — NEVER use training data memory for facts, dates, or events.\n3. If tool results contain the answer, state it directly and confidently. Do NOT say an event hasn't happened if the tool results show it has.\n4. Do NOT call any tools again — the results are already in your history. USE THEM NOW.`
252
+ }, sessionId);
253
+ continue; // Loop kembali ke Generator untuk revisi
254
+ }
255
+ else {
256
+ console.log(picocolors_1.default.green(`[🧠 Critic] Passed. Confidence: ${evaluation.factual_confidence?.toFixed(2)}, Completeness: ${evaluation.completeness?.toFixed(2)}.`));
257
+ }
258
+ }
259
+ }
260
+ catch {
261
+ // Python ML Engine tidak aktif — skip Critic, lanjut seperti biasa
262
+ }
263
+ }
264
+ // --- END CRITIC PASS ---
265
+ return cleanedContent || 'No response generated.';
132
266
  }
133
267
  let canFastReturnAll = true;
134
268
  let accumulatedResults = [];
@@ -205,8 +339,26 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
205
339
  canFastReturnAll = false;
206
340
  }
207
341
  }
208
- // V2 Optimization (Expanded in v1.7.4): Zero-LLM Fast Return for data-heavy and read-only tools
209
- // If all tools already return perfectly formatted markdown, skip the second LLM call to save 5-10s latency!
342
+ // P4: Self-reflection if ALL tools failed, inject reflection before next turn
343
+ const allFailed = accumulatedResults.length > 0 && accumulatedResults.every(r => r.startsWith('Error') || r.includes('[System Error]') || r.includes('[Security Blocked]'));
344
+ if (allFailed) {
345
+ consecutiveToolErrors++;
346
+ const reflection = `[SELF-REFLECTION] All ${accumulatedResults.length} tool call(s) failed (attempt ${consecutiveToolErrors}). ` +
347
+ `Errors: ${accumulatedResults.join(' | ')}. ` +
348
+ `Analyze WHY each failed. Options: (1) retry with corrected params, (2) use alternative tool, (3) inform user clearly. ` +
349
+ `Do NOT repeat the exact same failed call.`;
350
+ exports.logger.addEntry({ role: 'system', content: reflection }, sessionId);
351
+ console.log(picocolors_1.default.magenta(`[Self-Reflection] Turn ${turnCount}: all tools failed, injecting reflection.`));
352
+ if (consecutiveToolErrors >= 2) {
353
+ const errorSummary = `⚠️ Unable to complete this request after multiple attempts.\n${accumulatedResults.join('\n')}`;
354
+ exports.logger.addEntry({ role: 'assistant', content: errorSummary }, sessionId);
355
+ return errorSummary;
356
+ }
357
+ }
358
+ else {
359
+ consecutiveToolErrors = 0;
360
+ }
361
+ // V2 Optimization: Zero-LLM Fast Return for transaction tools
210
362
  if (canFastReturnAll && accumulatedResults.length > 0) {
211
363
  const finalContent = accumulatedResults.join('\n\n---\n\n');
212
364
  exports.logger.addEntry({ role: 'assistant', content: finalContent }, sessionId);
@@ -229,3 +381,173 @@ async function processOsIntent(input, role = 'user', onProgress, sessionId) {
229
381
  return errorMsg;
230
382
  }
231
383
  }
384
+ async function processOsIntentStream(input, onChunk, onProgress, sessionId) {
385
+ const config = (0, parser_1.loadConfig)();
386
+ exports.logger.addEntry({ role: 'user', content: input }, sessionId);
387
+ // --- MULTILINGUAL USER CORRECTION DETECTION ---
388
+ const correctionSignals = [
389
+ // ID
390
+ 'salah', 'ngawur', 'keliru', 'bukan', 'tidak benar', 'perbaiki', 'coba lagi',
391
+ // EN
392
+ 'wrong', 'incorrect', 'mistake', 'not right', 'false', 'bad', 'fix', 'try again',
393
+ // ES & FR
394
+ 'incorrecto', 'mal', 'equivocado', 'error', 'falso', 'faux', 'erreur', 'mauvais',
395
+ // DE & RU
396
+ 'falsch', 'inkorrekt', 'fehler', 'ошибка', 'неправильно', 'неверно',
397
+ // JP & ZH
398
+ '違う', '間違い', 'やり直して', '错误', '不对'
399
+ ];
400
+ if (correctionSignals.some(s => input.toLowerCase().includes(s))) {
401
+ exports.logger.addEntry({
402
+ role: 'system',
403
+ content: `[USER CORRECTION DETECTED] The user indicated your previous answer was WRONG, STALE, or INACCURATE.
404
+ CRITICAL INSTRUCTIONS:
405
+ 1. Do NOT just apologize and repeat the same data from your memory.
406
+ 2. The data in your training memory or previous tool calls is likely stale/incorrect.
407
+ 3. You MUST call a tool (like search_web or others) NOW to verify the facts with FRESH data.
408
+ 4. Base your new answer strictly on the NEW tool results.`
409
+ }, sessionId);
410
+ }
411
+ const pluginTools = registry_1.pluginManager.getAllToolDefinitions();
412
+ let activeTools = [...pluginTools].filter(t => (0, skillManager_1.isSkillActive)(t.function.name));
413
+ const { sanitizeHistoryForLLM } = require('../utils/historySanitizer');
414
+ try {
415
+ let turnCount = 0;
416
+ const MAX_TURNS = 10;
417
+ let fullResponse = '';
418
+ let criticHasFiredStream = false; // Critic Pass hanya aktif 1x per request
419
+ while (turnCount < MAX_TURNS) {
420
+ turnCount++;
421
+ const currentHistory = exports.logger.getHistory(sessionId);
422
+ const sanitizedHistory = sanitizeHistoryForLLM(currentHistory, activeTools, config.llm.provider);
423
+ const messages = [
424
+ { role: 'system', content: await getSystemPrompt('os', input) },
425
+ ...sanitizedHistory
426
+ ];
427
+ let streamedContent = '';
428
+ const response = await (0, llmUtils_1.executeWithRetry)(async (client) => {
429
+ return await client.stream({ model: config.llm.model, temperature: config.llm.temperature, messages, tools: activeTools }, (chunk) => {
430
+ streamedContent += chunk;
431
+ onChunk(chunk);
432
+ });
433
+ });
434
+ const responseMessage = response.message;
435
+ if (turnCount === 1)
436
+ tracker_1.Tracker.addMessage();
437
+ if (response.usage?.total_tokens)
438
+ tracker_1.Tracker.addTokens(response.usage.total_tokens, config.llm.provider);
439
+ tracker_1.Tracker.addEvent('llm.response', { provider: config.llm.provider, tool_calls: responseMessage.tool_calls?.length || 0 });
440
+ exports.logger.addEntry({
441
+ role: 'assistant',
442
+ content: responseMessage.content || '',
443
+ tool_calls: responseMessage.tool_calls,
444
+ }, sessionId);
445
+ if (!responseMessage.tool_calls || responseMessage.tool_calls.length === 0) {
446
+ let finalContent = responseMessage.content || 'No response generated.';
447
+ finalContent = finalContent.replace(/<(think|thought|thinking|reasoning|analysis|reflection)[\s\S]*?<\/\1>\n?/gi, '').trim();
448
+ // --- CRITIC PASS (Self-Improvement) ---
449
+ const isLongResponseStream = finalContent.length > 100;
450
+ if (isLongResponseStream && !criticHasFiredStream) {
451
+ criticHasFiredStream = true;
452
+ try {
453
+ const criticRes = await fetch('http://127.0.0.1:8000/cognitive/critic', {
454
+ method: 'POST',
455
+ headers: { 'Content-Type': 'application/json' },
456
+ body: JSON.stringify({ user_input: input, draft_answer: finalContent, current_utc_datetime: new Date().toISOString() })
457
+ });
458
+ if (criticRes.ok) {
459
+ const evaluation = await criticRes.json();
460
+ if (evaluation.needs_revision) {
461
+ console.log(picocolors_1.default.cyan(`[🧠 Critic] Revision needed. Confidence: ${evaluation.factual_confidence?.toFixed(2)}. Completeness: ${evaluation.completeness?.toFixed(2)}. Re-generating...`));
462
+ exports.logger.addEntry({
463
+ role: 'system',
464
+ content: `[SELF-CRITIQUE — MANDATORY REVISION] Your previous answer was REJECTED. Issues:\n${evaluation.revision_instructions}\n\nCRITICAL REVISION RULES:\n1. Look at the tool results (search_web, etc.) ALREADY in this conversation history above.\n2. Base your revised answer EXCLUSIVELY on those tool results — NEVER use training data memory for facts, dates, or events.\n3. If tool results contain the answer, state it directly and confidently. Do NOT say an event hasn't happened if the tool results show it has.\n4. Do NOT call any tools again — the results are already in your history. USE THEM NOW.`
465
+ }, sessionId);
466
+ continue; // Loop kembali ke Generator untuk revisi
467
+ }
468
+ else {
469
+ console.log(picocolors_1.default.green(`[🧠 Critic] Passed. Confidence: ${evaluation.factual_confidence?.toFixed(2)}, Completeness: ${evaluation.completeness?.toFixed(2)}.`));
470
+ }
471
+ }
472
+ }
473
+ catch {
474
+ // Python ML Engine tidak aktif — skip Critic, lanjut seperti biasa
475
+ }
476
+ }
477
+ // --- END CRITIC PASS ---
478
+ fullResponse = finalContent;
479
+ break;
480
+ }
481
+ // Tool calls detected — pause stream visually and execute tools
482
+ const fastReturnTools = ['transfer_token', 'transfer_native', 'swap_token', 'bridge_token', 'mint_nft', 'custom_tx', 'revoke_approval', 'supply_aave', 'deposit_yield_vault', 'provide_liquidity_v3'];
483
+ let canFastReturnAll = true;
484
+ const accumulatedResults = [];
485
+ for (const _toolCall of responseMessage.tool_calls) {
486
+ const toolCall = _toolCall;
487
+ const toolName = toolCall.function.name;
488
+ let result = '';
489
+ let args = {};
490
+ console.log(picocolors_1.default.yellow(`[⚡ Tool Execution] AI is calling ${toolName}...`));
491
+ if (onProgress)
492
+ onProgress(`_⚡ Running tool: ${toolName}..._`);
493
+ try {
494
+ let argStr = toolCall.function.arguments;
495
+ if (argStr && !argStr.trim().endsWith('}'))
496
+ argStr += '}';
497
+ args = JSON.parse(argStr);
498
+ }
499
+ catch (parseError) {
500
+ result = `[System Error] Arguments for ${toolName} must be valid JSON. Error: ${parseError.message}`;
501
+ exports.logger.addEntry({ role: 'tool', tool_call_id: toolCall.id, content: result }, sessionId);
502
+ continue;
503
+ }
504
+ if (!(0, skillManager_1.isSkillActive)(toolName)) {
505
+ result = `[System Error] Access denied: Skill '${toolName}' is currently disabled.`;
506
+ exports.logger.addEntry({ role: 'tool', tool_call_id: toolCall.id, content: result }, sessionId);
507
+ continue;
508
+ }
509
+ try {
510
+ const pluginResult = await registry_1.pluginManager.executeTool(toolName, args, { sessionId });
511
+ result = pluginResult !== null ? pluginResult : `Error: Tool ${toolName} is not implemented.`;
512
+ if (result.includes('[Security Blocked]') || result.startsWith('Error:')) {
513
+ console.log(picocolors_1.default.red(`[❌ Failed] Tool ${toolName} returned an error or was blocked.`));
514
+ }
515
+ else {
516
+ console.log(picocolors_1.default.green(`[✅ Success] Tool ${toolName} executed successfully.`));
517
+ }
518
+ }
519
+ catch (toolError) {
520
+ result = `Error executing ${toolName}: ${toolError.message}`;
521
+ console.error(picocolors_1.default.red(`[❌ Error Crash] Execution of ${toolName} failed: ${toolError.message}`));
522
+ }
523
+ exports.logger.addEntry({ role: 'tool', tool_call_id: toolCall.id, name: toolName, content: result }, sessionId);
524
+ accumulatedResults.push(result);
525
+ if (!fastReturnTools.includes(toolName))
526
+ canFastReturnAll = false;
527
+ }
528
+ if (canFastReturnAll && accumulatedResults.length > 0) {
529
+ const finalContent = accumulatedResults.join('\n\n---\n\n');
530
+ exports.logger.addEntry({ role: 'assistant', content: finalContent }, sessionId);
531
+ onChunk(finalContent);
532
+ fullResponse = finalContent;
533
+ break;
534
+ }
535
+ }
536
+ if (!fullResponse) {
537
+ const maxTurnMsg = '⚠️ Reached maximum interaction limit (10 turns). Please be more specific.';
538
+ exports.logger.addEntry({ role: 'assistant', content: maxTurnMsg }, sessionId);
539
+ fullResponse = maxTurnMsg;
540
+ }
541
+ return fullResponse;
542
+ }
543
+ catch (error) {
544
+ console.error('LLM Stream Error:', error);
545
+ const status = error?.status || error?.response?.status;
546
+ let errorMsg = '⚠️ All models are temporarily rate-limited. Please try again in a few minutes.';
547
+ if (status === 400 || (error.message && error.message.toLowerCase().includes('invalid'))) {
548
+ errorMsg = '⚠️ Failed to parse instruction. Please describe your command more specifically.';
549
+ }
550
+ exports.logger.addEntry({ role: 'assistant', content: errorMsg }, sessionId);
551
+ return errorMsg;
552
+ }
553
+ }