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.
- package/CHANGELOG.md +95 -47
- package/README.md +23 -19
- package/bin/nyxora.mjs +4 -6
- package/dist/launcher.js +44 -8
- package/dist/packages/core/src/agent/bridgeWatcher.js +3 -2
- package/dist/packages/core/src/agent/cronManager.js +2 -2
- package/dist/packages/core/src/agent/llmProvider.js +242 -0
- package/dist/packages/core/src/agent/nyxDaemon.js +97 -0
- package/dist/packages/core/src/agent/osAgent.js +203 -29
- package/dist/packages/core/src/agent/reasoning.js +353 -60
- package/dist/packages/core/src/agent/reasoningScratchpad.js +47 -0
- package/dist/packages/core/src/agent/transactionManager.js +36 -31
- package/dist/packages/core/src/agent/web3Agent.js +263 -37
- package/dist/packages/core/src/cognitive/cognitiveManager.js +63 -10
- package/dist/packages/core/src/config/parser.js +10 -4
- package/dist/packages/core/src/gateway/chat.js +56 -13
- package/dist/packages/core/src/gateway/cli.js +3 -0
- package/dist/packages/core/src/gateway/discordAdapter.js +81 -0
- package/dist/packages/core/src/gateway/server.js +58 -9
- package/dist/packages/core/src/gateway/setup-ml.js +64 -0
- package/dist/packages/core/src/gateway/setup.js +39 -3
- package/dist/packages/core/src/gateway/telegram.js +120 -24
- package/dist/packages/core/src/memory/episodic.js +47 -3
- package/dist/packages/core/src/memory/logger.js +120 -2
- package/dist/packages/core/src/memory/promotionEngine.js +18 -5
- package/dist/packages/core/src/system/agentskills.js +10 -0
- package/dist/packages/core/src/system/plugins/GoogleWorkspacePlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemCorePlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemExternalPlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemPluginInstallerPlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemSocialPlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemWebPlugin.js +1 -1
- package/dist/packages/core/src/system/plugins/SystemWorkspacePlugin.js +3 -3
- package/dist/packages/core/src/system/plugins/createSkill.js +1 -1
- package/dist/packages/core/src/system/skillExtractor.js +16 -5
- package/dist/packages/core/src/system/skills/forgetMemory.js +6 -4
- package/dist/packages/core/src/system/skills/scheduleTask.js +7 -2
- package/dist/packages/core/src/test_mainnet.js +45 -0
- package/dist/packages/core/src/utils/contextSummarizer.js +82 -0
- package/dist/packages/core/src/utils/skillManager.js +1 -1
- package/dist/packages/core/src/utils/streamSimulator.js +85 -0
- package/dist/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.js +28 -11
- package/dist/packages/core/src/web3/aggregator/providers/OpBridgeProvider.js +41 -27
- package/dist/packages/core/src/web3/aggregator/providers/TestnetSwapProvider.js +65 -0
- package/dist/packages/core/src/web3/aggregator/routeSelector.js +7 -1
- package/dist/packages/core/src/web3/plugins/Web3DefiPlugin.js +1 -1
- package/dist/packages/core/src/web3/plugins/Web3MarketPlugin.js +5 -125
- package/dist/packages/core/src/web3/plugins/Web3SecurityPlugin.js +1 -1
- package/dist/packages/core/src/web3/plugins/Web3WalletPlugin.js +1 -1
- package/dist/packages/core/src/web3/skills/bridgeToken.js +19 -4
- package/dist/packages/core/src/web3/skills/checkAddress.js +2 -0
- package/dist/packages/core/src/web3/skills/checkPortfolio.js +22 -2
- package/dist/packages/core/src/web3/skills/checkSecurity.js +2 -0
- package/dist/packages/core/src/web3/skills/confirmPendingTx.js +1 -1
- package/dist/packages/core/src/web3/skills/createLimitOrder.js +15 -1
- package/dist/packages/core/src/web3/skills/customTx.js +3 -0
- package/dist/packages/core/src/web3/skills/defiLending.js +2 -0
- package/dist/packages/core/src/web3/skills/getBalance.js +2 -0
- package/dist/packages/core/src/web3/skills/getPrice.js +134 -27
- package/dist/packages/core/src/web3/skills/getTxHistory.js +2 -0
- package/dist/packages/core/src/web3/skills/marketAnalysis.js +28 -191
- package/dist/packages/core/src/web3/skills/mintNft.js +3 -0
- package/dist/packages/core/src/web3/skills/provideLiquidity.js +16 -12
- package/dist/packages/core/src/web3/skills/revokeApprovals.js +2 -0
- package/dist/packages/core/src/web3/skills/swapToken.js +20 -2
- package/dist/packages/core/src/web3/skills/transfer.js +2 -0
- package/dist/packages/core/src/web3/skills/yieldVault.js +2 -0
- package/dist/packages/core/src/web3/utils/chains.js +19 -0
- package/dist/packages/core/src/web3/utils/marketEngine.js +26 -33
- package/dist/packages/signer/src/NyxoraSigner.js +181 -0
- package/dist/packages/signer/src/index.js +17 -0
- package/dist/packages/signer/src/server.js +25 -161
- package/launcher.ts +38 -9
- package/package.json +6 -2
- package/packages/core/package.json +21 -10
- package/packages/core/src/agent/bridgeWatcher.ts +3 -2
- package/packages/core/src/agent/cronManager.ts +2 -2
- package/packages/core/src/agent/llmProvider.ts +219 -0
- package/packages/core/src/agent/nyxDaemon.ts +104 -0
- package/packages/core/src/agent/osAgent.ts +230 -32
- package/packages/core/src/agent/reasoning.ts +376 -64
- package/packages/core/src/agent/reasoningScratchpad.ts +45 -0
- package/packages/core/src/agent/transactionManager.ts +36 -28
- package/packages/core/src/agent/web3Agent.ts +291 -40
- package/packages/core/src/cognitive/cognitiveManager.ts +65 -10
- package/packages/core/src/cognitive/prompts/web3/market-analysis.md +24 -0
- package/packages/core/src/cognitive/prompts/web3/portfolio-review.md +29 -0
- package/packages/core/src/cognitive/prompts/web3/risk-assessment.md +28 -0
- package/packages/core/src/cognitive/prompts/web3/trade-planning.md +30 -0
- package/packages/core/src/config/parser.ts +15 -4
- package/packages/core/src/gateway/chat.ts +57 -15
- package/packages/core/src/gateway/cli.ts +4 -0
- package/packages/core/src/gateway/discordAdapter.ts +87 -0
- package/packages/core/src/gateway/server.ts +66 -10
- package/packages/core/src/gateway/setup-ml.ts +68 -0
- package/packages/core/src/gateway/setup.ts +41 -3
- package/packages/core/src/gateway/telegram.ts +138 -27
- package/packages/core/src/memory/episodic.ts +64 -3
- package/packages/core/src/memory/logger.ts +142 -2
- package/packages/core/src/memory/promotionEngine.ts +19 -5
- package/packages/core/src/system/agentskills.ts +10 -0
- package/packages/core/src/system/plugins/GoogleWorkspacePlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemCorePlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemExternalPlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemPluginInstallerPlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemSocialPlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemWebPlugin.ts +1 -1
- package/packages/core/src/system/plugins/SystemWorkspacePlugin.ts +3 -3
- package/packages/core/src/system/plugins/createSkill.ts +1 -1
- package/packages/core/src/system/skillExtractor.ts +16 -5
- package/packages/core/src/system/skills/forgetMemory.ts +7 -4
- package/packages/core/src/system/skills/scheduleTask.ts +7 -2
- package/packages/core/src/utils/contextSummarizer.ts +100 -0
- package/packages/core/src/utils/skillManager.ts +1 -1
- package/packages/core/src/utils/streamSimulator.ts +88 -0
- package/packages/core/src/web3/aggregator/providers/ArbitrumBridgeProvider.ts +30 -11
- package/packages/core/src/web3/aggregator/providers/OpBridgeProvider.ts +43 -29
- package/packages/core/src/web3/aggregator/routeSelector.ts +6 -1
- package/packages/core/src/web3/plugins/Web3DefiPlugin.ts +1 -1
- package/packages/core/src/web3/plugins/Web3MarketPlugin.ts +6 -125
- package/packages/core/src/web3/plugins/Web3SecurityPlugin.ts +1 -1
- package/packages/core/src/web3/plugins/Web3WalletPlugin.ts +1 -1
- package/packages/core/src/web3/skills/bridgeToken.ts +21 -7
- package/packages/core/src/web3/skills/checkAddress.ts +2 -0
- package/packages/core/src/web3/skills/checkPortfolio.ts +23 -2
- package/packages/core/src/web3/skills/checkSecurity.ts +2 -0
- package/packages/core/src/web3/skills/confirmPendingTx.ts +1 -1
- package/packages/core/src/web3/skills/createLimitOrder.ts +17 -2
- package/packages/core/src/web3/skills/customTx.ts +3 -0
- package/packages/core/src/web3/skills/defiLending.ts +2 -0
- package/packages/core/src/web3/skills/getBalance.ts +2 -0
- package/packages/core/src/web3/skills/getPrice.ts +134 -30
- package/packages/core/src/web3/skills/getTxHistory.ts +2 -0
- package/packages/core/src/web3/skills/marketAnalysis.ts +45 -188
- package/packages/core/src/web3/skills/mintNft.ts +3 -0
- package/packages/core/src/web3/skills/provideLiquidity.ts +16 -10
- package/packages/core/src/web3/skills/revokeApprovals.ts +2 -0
- package/packages/core/src/web3/skills/swapToken.ts +20 -3
- package/packages/core/src/web3/skills/transfer.ts +2 -0
- package/packages/core/src/web3/skills/yieldVault.ts +2 -0
- package/packages/core/src/web3/utils/chains.ts +12 -0
- package/packages/core/src/web3/utils/marketEngine.ts +27 -33
- package/packages/dashboard/dist/assets/index-BTfp141V.js +18 -0
- package/packages/dashboard/dist/assets/index-DK2sTU47.css +1 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package.json +10 -10
- package/packages/mcp-server/dist/server.js +5 -1
- package/packages/mcp-server/package.json +6 -6
- package/packages/mcp-server/src/server.ts +11 -7
- package/packages/policy/package.json +3 -3
- package/packages/signer/package.json +16 -6
- package/packages/signer/src/NyxoraSigner.ts +161 -0
- package/packages/signer/src/index.ts +1 -0
- package/packages/signer/src/server.ts +25 -135
- package/dist/packages/core/src/agent/honchoDaemon.js +0 -91
- package/dist/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -54
- package/dist/packages/core/src/gateway/test.js +0 -15
- package/dist/packages/core/src/web3/Web3DefiPlugin.js +0 -28
- package/dist/packages/core/src/web3/aggregator/aggregatorMainnet.js +0 -260
- package/dist/packages/core/src/web3/aggregator/aggregatorTestnet.js +0 -119
- package/dist/packages/core/src/web3/skills/nativeOpBridge.js +0 -71
- package/packages/core/src/agent/honchoDaemon.ts +0 -96
- package/packages/core/src/cognitive/prompts/autonomous/binance-trading-integration.md +0 -41
- package/packages/core/src/plugin/registry.test.ts +0 -46
- package/packages/core/src/utils/formatter.test.ts +0 -41
- package/packages/dashboard/dist/assets/index-CSoNa5cx.css +0 -1
- 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
|
-
|
|
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
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
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
|
-
},
|
|
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();
|