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
package/dist/launcher.js CHANGED
@@ -26,20 +26,28 @@ const env = {
26
26
  ...process.env,
27
27
  INTERNAL_AUTH_TOKEN,
28
28
  SIGNER_SOCKET_PATH: '/tmp/nyxora-signer.sock',
29
- TS_NODE_CACHE: 'false'
29
+ TS_NODE_CACHE: 'false',
30
+ PYTHONUNBUFFERED: '1'
30
31
  };
31
- const spawnService = (name, command, args, env, inheritStdio = false) => {
32
+ const spawnService = (name, command, args, env, inheritStdio = false, cwd) => {
32
33
  let child;
33
34
  let crashCount = 0;
34
35
  let crashWindowStart = Date.now();
35
36
  let isShuttingDown = false;
36
37
  const startProcess = () => {
37
- child = (0, child_process_1.spawn)(command, args, { env, stdio: inheritStdio ? 'inherit' : 'pipe' });
38
+ const spawnOpts = { env, stdio: inheritStdio ? 'inherit' : 'pipe' };
39
+ if (cwd)
40
+ spawnOpts.cwd = cwd;
41
+ child = (0, child_process_1.spawn)(command, args, spawnOpts);
42
+ child.on('error', (err) => {
43
+ console.error(`[Launcher] Failed to spawn ${name}:`, err.message);
44
+ isShuttingDown = true; // Prevent retry loop if spawn fails
45
+ });
38
46
  if (!inheritStdio) {
39
47
  child.stdout?.on('data', (data) => process.stdout.write(`[${name}] ${data}`));
40
48
  child.stderr?.on('data', (data) => {
41
49
  const msg = data.toString();
42
- if (msg.toLowerCase().includes('warn')) {
50
+ if (msg.toLowerCase().includes('warn') || msg.toLowerCase().includes('info')) {
43
51
  process.stderr.write(`[${name}] ${msg}`);
44
52
  }
45
53
  else {
@@ -98,6 +106,14 @@ const spawnService = (name, command, args, env, inheritStdio = false) => {
98
106
  }
99
107
  catch (e) { }
100
108
  }
109
+ },
110
+ forceKill: () => {
111
+ if (child && !child.killed && child.pid) {
112
+ try {
113
+ process.kill(child.pid, 'SIGKILL');
114
+ }
115
+ catch (e) { }
116
+ }
101
117
  }
102
118
  };
103
119
  };
@@ -122,10 +138,23 @@ setTimeout(() => {
122
138
  const policy = spawnService('Policy', cmd, [...baseArgs, policyPath], env);
123
139
  children.push(policy);
124
140
  setTimeout(() => {
125
- const corePath = path_1.default.join(__dirnameResolved, `packages/core/src/gateway/cli${ext}`);
126
- const args = process.argv.slice(2);
127
- const core = spawnService('Core', cmd, [...baseArgs, corePath, ...args], env, true);
128
- children.push(core);
141
+ // Spawn ML Engine (Python Sidecar)
142
+ const pythonPath = path_1.default.join(process.env.HOME || process.env.USERPROFILE || '', '.nyxora', 'ml-engine', 'venv', 'bin', 'python');
143
+ if (fs_1.default.existsSync(pythonPath)) {
144
+ const mlDir = path_1.default.join(__dirnameResolved, 'packages', 'ml-engine');
145
+ const mlArgs = ['-m', 'uvicorn', 'main:app', '--host', '127.0.0.1', '--port', '8000'];
146
+ const mlEngine = spawnService('ML Engine', pythonPath, mlArgs, env, false, mlDir);
147
+ children.push(mlEngine);
148
+ }
149
+ else {
150
+ console.warn('[Launcher] Warning: Python virtual environment not found. Did you run setup?');
151
+ }
152
+ setTimeout(() => {
153
+ const corePath = path_1.default.join(__dirnameResolved, `packages/core/src/gateway/cli${ext}`);
154
+ const args = process.argv.slice(2);
155
+ const core = spawnService('Core', cmd, [...baseArgs, corePath, ...args], env, true);
156
+ children.push(core);
157
+ }, 1000);
129
158
  }, 1000);
130
159
  }, 1000);
131
160
  // Ensure all child processes are killed when launcher exits
@@ -138,8 +167,15 @@ const cleanup = () => {
138
167
  children.forEach(c => c.kill());
139
168
  // Give them a moment to cleanup
140
169
  setTimeout(() => {
170
+ children.forEach(c => {
171
+ try {
172
+ c.forceKill();
173
+ }
174
+ catch (e) { }
175
+ });
141
176
  try {
142
177
  require('child_process').execSync('pkill -f ts-node');
178
+ require('child_process').execSync('pkill -f uvicorn');
143
179
  }
144
180
  catch (e) { }
145
181
  process.exit(0);
@@ -8,7 +8,8 @@ const parser_1 = require("../config/parser");
8
8
  // to fetch the Merkle Proof and call proveWithdrawalTransaction on L1.
9
9
  // For the scope of this architecture prototype, we simulate the Challenge Period
10
10
  // watcher by using a time-delay, representing the exact asynchronous behavior.
11
- const CHALLENGE_PERIOD_MS = 2 * 60 * 1000; // Simulating a 2-minute challenge period for testnet demo
11
+ // Actual 7-day challenge period for OP Stack and Arbitrum withdrawals
12
+ const CHALLENGE_PERIOD_MS = 7 * 24 * 60 * 60 * 1000;
12
13
  function startBridgeWatcher() {
13
14
  console.log('[Bridge Watcher] Started background daemon for asynchronous L2 withdrawals');
14
15
  setInterval(async () => {
@@ -30,5 +31,5 @@ function startBridgeWatcher() {
30
31
  }
31
32
  }
32
33
  }
33
- }, 30000); // Check every 30 seconds
34
+ }, 12 * 60 * 60 * 1000); // Check every 12 hours
34
35
  }
@@ -44,7 +44,7 @@ const crypto_1 = require("crypto");
44
44
  const picocolors_1 = __importDefault(require("picocolors"));
45
45
  class CronManager {
46
46
  jobs = new Map();
47
- addJob(expression, prompt) {
47
+ addJob(expression, prompt, sessionId) {
48
48
  const id = (0, crypto_1.randomUUID)();
49
49
  // Validate expression
50
50
  try {
@@ -59,7 +59,7 @@ class CronManager {
59
59
  // Dynamically import processUserInput to avoid circular dependencies
60
60
  const { processUserInput } = await Promise.resolve().then(() => __importStar(require('./reasoning')));
61
61
  // Execute the prompt as a background system task
62
- const response = await processUserInput(prompt, 'system', undefined, `cron-${id}`);
62
+ const response = await processUserInput(prompt, 'system', undefined, sessionId || `cron-${id}`);
63
63
  // Push notification to Telegram if configured
64
64
  const config = (0, parser_1.loadConfig)();
65
65
  if (config.integrations?.telegram?.enabled && config.integrations?.telegram?.authorized_chat_id) {
@@ -16,6 +16,50 @@ class OpenAIAdapter {
16
16
  usage: response.usage ? { total_tokens: response.usage.total_tokens } : undefined
17
17
  };
18
18
  }
19
+ async stream(request, onChunk) {
20
+ try {
21
+ const streamRes = await this.client.chat.completions.create({ ...request, stream: true });
22
+ let fullContent = '';
23
+ const toolCallsMap = {};
24
+ for await (const chunk of streamRes) {
25
+ const delta = chunk.choices[0]?.delta;
26
+ if (delta?.content) {
27
+ fullContent += delta.content;
28
+ onChunk(delta.content);
29
+ }
30
+ if (delta?.tool_calls) {
31
+ for (const tc of delta.tool_calls) {
32
+ if (!toolCallsMap[tc.index]) {
33
+ toolCallsMap[tc.index] = { id: tc.id || '', type: 'function', function: { name: tc.function?.name || '', arguments: tc.function?.arguments || '' } };
34
+ }
35
+ else {
36
+ if (tc.id)
37
+ toolCallsMap[tc.index].id = tc.id;
38
+ if (tc.function?.name)
39
+ toolCallsMap[tc.index].function.name += tc.function.name;
40
+ if (tc.function?.arguments)
41
+ toolCallsMap[tc.index].function.arguments += tc.function.arguments;
42
+ }
43
+ }
44
+ }
45
+ }
46
+ const toolCalls = Object.values(toolCallsMap);
47
+ return {
48
+ message: {
49
+ content: fullContent || null,
50
+ tool_calls: toolCalls.length > 0 ? toolCalls : undefined
51
+ }
52
+ };
53
+ }
54
+ catch (e) {
55
+ // Fallback to non-streaming if streaming fails
56
+ const chatRes = await this.chat(request);
57
+ if (chatRes.message.content) {
58
+ onChunk(chatRes.message.content);
59
+ }
60
+ return chatRes;
61
+ }
62
+ }
19
63
  }
20
64
  exports.OpenAIAdapter = OpenAIAdapter;
21
65
  class AnthropicAdapter {
@@ -129,6 +173,84 @@ class AnthropicAdapter {
129
173
  usage: response.usage ? { total_tokens: response.usage.input_tokens + response.usage.output_tokens } : undefined
130
174
  };
131
175
  }
176
+ async stream(request, onChunk) {
177
+ try {
178
+ // Build the same message format as chat()
179
+ let systemPrompt = '';
180
+ const anthropicMessages = [];
181
+ for (const m of request.messages) {
182
+ if (m.role === 'system') {
183
+ systemPrompt = m.content;
184
+ continue;
185
+ }
186
+ if (m.role === 'user') {
187
+ anthropicMessages.push({ role: 'user', content: m.content });
188
+ }
189
+ else if (m.role === 'assistant') {
190
+ const blocks = [];
191
+ if (m.content)
192
+ blocks.push({ type: 'text', text: m.content });
193
+ if (m.tool_calls)
194
+ m.tool_calls.forEach((tc) => {
195
+ try {
196
+ blocks.push({ type: 'tool_use', id: tc.id, name: tc.function.name, input: JSON.parse(tc.function.arguments) });
197
+ }
198
+ catch { }
199
+ });
200
+ anthropicMessages.push({ role: 'assistant', content: blocks.length > 0 ? blocks : m.content });
201
+ }
202
+ else if (m.role === 'tool') {
203
+ anthropicMessages.push({ role: 'user', content: [{ type: 'tool_result', tool_use_id: m.tool_call_id, content: m.content }] });
204
+ }
205
+ }
206
+ const mergedAnthropic = [];
207
+ for (const m of anthropicMessages) {
208
+ const last = mergedAnthropic[mergedAnthropic.length - 1];
209
+ if (last && last.role === m.role) {
210
+ if (Array.isArray(last.content) && Array.isArray(m.content))
211
+ last.content.push(...m.content);
212
+ else if (typeof last.content === 'string' && typeof m.content === 'string')
213
+ last.content += '\n\n' + m.content;
214
+ else if (Array.isArray(last.content) && typeof m.content === 'string')
215
+ last.content.push({ type: 'text', text: m.content });
216
+ else
217
+ last.content = [{ type: 'text', text: typeof last.content === 'string' ? last.content : '' }, ...m.content];
218
+ }
219
+ else {
220
+ mergedAnthropic.push(m);
221
+ }
222
+ }
223
+ const anthropicTools = request.tools?.map(t => ({ name: t.function.name, description: t.function.description, input_schema: t.function.parameters }));
224
+ const stream = this.client.messages.stream({
225
+ model: request.model,
226
+ system: systemPrompt,
227
+ messages: mergedAnthropic,
228
+ tools: anthropicTools,
229
+ temperature: request.temperature,
230
+ max_tokens: request.max_tokens || 4096
231
+ });
232
+ let fullContent = '';
233
+ const toolCalls = [];
234
+ for await (const event of stream) {
235
+ if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
236
+ fullContent += event.delta.text;
237
+ onChunk(event.delta.text);
238
+ }
239
+ if (event.type === 'content_block_start' && event.content_block.type === 'tool_use') {
240
+ toolCalls.push({ id: event.content_block.id, type: 'function', function: { name: event.content_block.name, arguments: '' } });
241
+ }
242
+ if (event.type === 'content_block_delta' && event.delta.type === 'input_json_delta') {
243
+ const last = toolCalls[toolCalls.length - 1];
244
+ if (last)
245
+ last.function.arguments += event.delta.partial_json;
246
+ }
247
+ }
248
+ return { message: { content: fullContent || null, tool_calls: toolCalls.length > 0 ? toolCalls : undefined } };
249
+ }
250
+ catch {
251
+ return this.chat(request);
252
+ }
253
+ }
132
254
  }
133
255
  exports.AnthropicAdapter = AnthropicAdapter;
134
256
  class GeminiAdapter {
@@ -268,5 +390,125 @@ class GeminiAdapter {
268
390
  usage: totalTokens > 0 ? { total_tokens: totalTokens } : undefined
269
391
  };
270
392
  }
393
+ async stream(request, onChunk) {
394
+ let systemInstruction = '';
395
+ const contents = [];
396
+ for (const m of request.messages) {
397
+ if (m.role === 'system') {
398
+ systemInstruction = m.content;
399
+ continue;
400
+ }
401
+ if (m.role === 'user') {
402
+ contents.push({ role: 'user', parts: [{ text: m.content }] });
403
+ }
404
+ else if (m.role === 'assistant') {
405
+ const parts = [];
406
+ if (m.content)
407
+ parts.push({ text: m.content });
408
+ if (m.tool_calls) {
409
+ m.tool_calls.forEach((tc) => {
410
+ try {
411
+ parts.push({ functionCall: { name: tc.function.name, args: JSON.parse(tc.function.arguments) } });
412
+ }
413
+ catch { }
414
+ });
415
+ }
416
+ if (parts.length > 0)
417
+ contents.push({ role: 'model', parts });
418
+ }
419
+ else if (m.role === 'tool') {
420
+ contents.push({ role: 'user', parts: [{ functionResponse: { name: m.name || 'unknown_tool', response: { result: m.content } } }] });
421
+ }
422
+ }
423
+ const mergedContents = [];
424
+ for (const m of contents) {
425
+ const last = mergedContents[mergedContents.length - 1];
426
+ if (last && last.role === m.role)
427
+ last.parts.push(...m.parts);
428
+ else
429
+ mergedContents.push(m);
430
+ }
431
+ let tools = undefined;
432
+ if (request.tools && request.tools.length > 0) {
433
+ tools = [{ functionDeclarations: request.tools.map(t => ({ name: t.function.name, description: t.function.description, parameters: t.function.parameters })) }];
434
+ }
435
+ const payload = {
436
+ contents: mergedContents,
437
+ generationConfig: { temperature: request.temperature || 0.7 },
438
+ safetySettings: [
439
+ { category: 'HARM_CATEGORY_DANGEROUS_CONTENT', threshold: 'BLOCK_NONE' },
440
+ { category: 'HARM_CATEGORY_HARASSMENT', threshold: 'BLOCK_NONE' },
441
+ { category: 'HARM_CATEGORY_HATE_SPEECH', threshold: 'BLOCK_NONE' },
442
+ { category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', threshold: 'BLOCK_NONE' }
443
+ ]
444
+ };
445
+ if (systemInstruction)
446
+ payload.systemInstruction = { parts: [{ text: systemInstruction }] };
447
+ if (tools)
448
+ payload.tools = tools;
449
+ try {
450
+ const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${request.model}:streamGenerateContent?alt=sse&key=${this.apiKey}`, {
451
+ method: 'POST',
452
+ headers: { 'Content-Type': 'application/json' },
453
+ body: JSON.stringify(payload)
454
+ });
455
+ if (!response.ok)
456
+ return this.chat(request);
457
+ let contentStr = '';
458
+ const toolCalls = [];
459
+ let totalTokens = 0;
460
+ const reader = response.body?.getReader();
461
+ const decoder = new TextDecoder();
462
+ if (reader) {
463
+ let buffer = '';
464
+ while (true) {
465
+ const { done, value } = await reader.read();
466
+ if (done)
467
+ break;
468
+ buffer += decoder.decode(value, { stream: true });
469
+ const lines = buffer.split('\n');
470
+ buffer = lines.pop() || '';
471
+ for (const line of lines) {
472
+ if (!line.startsWith('data: '))
473
+ continue;
474
+ const raw = line.slice(6).trim();
475
+ if (!raw || raw === '[DONE]')
476
+ continue;
477
+ try {
478
+ const data = JSON.parse(raw);
479
+ if (data.candidates && data.candidates.length > 0) {
480
+ const candidate = data.candidates[0];
481
+ if (candidate.content && candidate.content.parts) {
482
+ for (const part of candidate.content.parts) {
483
+ if (part.text) {
484
+ contentStr += part.text;
485
+ onChunk(part.text);
486
+ }
487
+ else if (part.functionCall) {
488
+ toolCalls.push({
489
+ id: `call_${Math.random().toString(36).substring(7)}`,
490
+ type: 'function',
491
+ function: { name: part.functionCall.name, arguments: JSON.stringify(part.functionCall.args || {}) }
492
+ });
493
+ }
494
+ }
495
+ }
496
+ }
497
+ if (data.usageMetadata?.totalTokenCount)
498
+ totalTokens = data.usageMetadata.totalTokenCount;
499
+ }
500
+ catch { }
501
+ }
502
+ }
503
+ }
504
+ return {
505
+ message: { content: contentStr || null, tool_calls: toolCalls.length > 0 ? toolCalls : undefined },
506
+ usage: totalTokens > 0 ? { total_tokens: totalTokens } : undefined
507
+ };
508
+ }
509
+ catch {
510
+ return this.chat(request);
511
+ }
512
+ }
271
513
  }
272
514
  exports.GeminiAdapter = GeminiAdapter;
@@ -0,0 +1,97 @@
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.nyxDaemon = exports.NyxDaemon = void 0;
7
+ const episodic_1 = require("../memory/episodic");
8
+ const reasoning_1 = require("./reasoning");
9
+ const picocolors_1 = __importDefault(require("picocolors"));
10
+ class NyxDaemon {
11
+ isProcessing = false;
12
+ interval = null;
13
+ initialTimeout = null;
14
+ start() {
15
+ if (this.interval)
16
+ return;
17
+ // Initial run after 30 seconds (faster persona availability for new sessions)
18
+ this.initialTimeout = setTimeout(() => {
19
+ this.runAudit();
20
+ }, 30 * 1000);
21
+ // Audit memory every 30 minutes
22
+ this.interval = setInterval(() => {
23
+ this.runAudit();
24
+ }, 30 * 60 * 1000);
25
+ console.log(picocolors_1.default.magenta('[Nyx] Dialectic User Modeling daemon started.'));
26
+ }
27
+ stop() {
28
+ if (this.initialTimeout) {
29
+ clearTimeout(this.initialTimeout);
30
+ this.initialTimeout = null;
31
+ }
32
+ if (this.interval) {
33
+ clearInterval(this.interval);
34
+ this.interval = null;
35
+ console.log(picocolors_1.default.magenta('[Nyx] Daemon stopped.'));
36
+ }
37
+ }
38
+ async runAudit() {
39
+ if (this.isProcessing)
40
+ return;
41
+ this.isProcessing = true;
42
+ try {
43
+ console.log(picocolors_1.default.magenta('[Nyx] Running dialectic user modeling...'));
44
+ // Fix A: Use getRecentMessagesAllSessions so Telegram/Discord history is included.
45
+ // Previously getHistory(undefined) only read session_id IS NULL — Telegram sessions have a session_id.
46
+ const history = reasoning_1.logger.getRecentMessagesAllSessions(30);
47
+ // Fix B: Filter noise — only send plain user & assistant text messages to the LLM.
48
+ // Skip tool messages, system messages, and assistant entries that only contain tool_calls.
49
+ const conversationOnly = history.filter(m => (m.role === 'user' || m.role === 'assistant') &&
50
+ m.content &&
51
+ m.content.trim().length > 0 &&
52
+ !m.tool_calls);
53
+ if (conversationOnly.length < 5) {
54
+ console.log(picocolors_1.default.magenta('[Nyx] Not enough conversation messages to analyze, skipping.'));
55
+ this.isProcessing = false;
56
+ return;
57
+ }
58
+ // Kirim riwayat percakapan ke Python ML Engine untuk diproses oleh LangChain
59
+ const res = await fetch('http://localhost:8000/cognitive/reason', {
60
+ method: 'POST',
61
+ headers: { 'Content-Type': 'application/json' },
62
+ body: JSON.stringify({ messages: conversationOnly })
63
+ });
64
+ if (!res.ok) {
65
+ throw new Error(`Python ML Engine returned ${res.status}: ${await res.text()}`);
66
+ }
67
+ const traits = await res.json();
68
+ try {
69
+ if (traits && typeof traits === 'object' && !Array.isArray(traits)) {
70
+ const categories = ['language', 'tone', 'trading_style', 'behavior'];
71
+ for (const cat of categories) {
72
+ const value = traits[cat];
73
+ if (value && typeof value === 'string' && value.trim()) {
74
+ // Category-based upsert: confidence accumulates correctly per category
75
+ episodic_1.episodicDB.upsertPersonaByCategory(cat, value.trim(), 0.5, 'nyx_daemon');
76
+ console.log(picocolors_1.default.magenta(`[Nyx] Updated persona [${cat}]: ${value.trim()}`));
77
+ }
78
+ }
79
+ }
80
+ else {
81
+ console.log(picocolors_1.default.magenta('[Nyx] No strong traits found in this audit cycle.'));
82
+ }
83
+ }
84
+ catch (e) {
85
+ console.error(picocolors_1.default.red('[Nyx] Failed to process traits from Python'), traits);
86
+ }
87
+ }
88
+ catch (e) {
89
+ console.error(picocolors_1.default.red(`[Nyx] Analysis failed: ${e.message}`));
90
+ }
91
+ finally {
92
+ this.isProcessing = false;
93
+ }
94
+ }
95
+ }
96
+ exports.NyxDaemon = NyxDaemon;
97
+ exports.nyxDaemon = new NyxDaemon();