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
|
@@ -24,15 +24,22 @@ function formatToTelegramHTML(text) {
|
|
|
24
24
|
.replace(/&/g, '&')
|
|
25
25
|
.replace(/</g, '<')
|
|
26
26
|
.replace(/>/g, '>');
|
|
27
|
-
html = html.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>');
|
|
28
|
-
html = html.replace(/(?<!^|\n)\*(?!\s)(.*?)(?<!\s)\*/g, '<i>$1</i>');
|
|
29
|
-
html = html.replace(/_(.*?)_/g, '<i>$1</i>');
|
|
30
|
-
html = html.replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>');
|
|
31
|
-
html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
|
|
32
27
|
html = html.replace(/<thought>[\s\S]*?<\/thought>\n?/g, '');
|
|
33
28
|
html = html.replace(/<thought>[\s\S]*?<\/thought>\n?/g, '');
|
|
34
29
|
html = html.replace(/<think>[\s\S]*?<\/think>\n?/g, '');
|
|
35
30
|
html = html.replace(/<think>[\s\S]*?<\/think>\n?/g, '');
|
|
31
|
+
html = html.replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>');
|
|
32
|
+
html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
|
|
33
|
+
html = html.replace(/\*\*(.*?)\*\*/g, (match, p1) => {
|
|
34
|
+
if (p1.includes('<pre>') || p1.includes('<code>'))
|
|
35
|
+
return match;
|
|
36
|
+
return `<b>${p1}</b>`;
|
|
37
|
+
});
|
|
38
|
+
html = html.replace(/(?<!^|\n)\*(?!\s)(.*?)(?<!\s)\*/g, (match, p1) => {
|
|
39
|
+
if (p1.includes('<b>') || p1.includes('</b>') || p1.includes('<pre>') || p1.includes('<code>'))
|
|
40
|
+
return match;
|
|
41
|
+
return `<i>${p1}</i>`;
|
|
42
|
+
});
|
|
36
43
|
const tableRegex = /(?:\|.*\|(?:\n|$))+/g;
|
|
37
44
|
html = html.replace(tableRegex, (match) => {
|
|
38
45
|
return `<pre>${match.trim()}</pre>\n`;
|
|
@@ -51,6 +58,20 @@ function startTelegramBot() {
|
|
|
51
58
|
globalBotInstance = bot;
|
|
52
59
|
const throttler = (0, transformer_throttler_1.apiThrottler)();
|
|
53
60
|
bot.api.config.use(throttler);
|
|
61
|
+
bot.api.config.use(async (prev, method, payload, signal) => {
|
|
62
|
+
try {
|
|
63
|
+
return await prev(method, payload, signal);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (method === 'getUpdates' && err.message?.includes('ETIMEDOUT')) {
|
|
67
|
+
console.log(picocolors_1.default.yellow('[Telegram] API connection lost (Timeout). Retrying automatically...'));
|
|
68
|
+
}
|
|
69
|
+
else if (method === 'getUpdates') {
|
|
70
|
+
console.log(picocolors_1.default.yellow(`[Telegram] Failed to fetch updates: ${err.message}`));
|
|
71
|
+
}
|
|
72
|
+
throw err; // Rethrow so the runner can gracefully backoff and retry
|
|
73
|
+
}
|
|
74
|
+
});
|
|
54
75
|
const isPaired = !!config.integrations?.telegram?.authorized_chat_id;
|
|
55
76
|
let generatedPin = '';
|
|
56
77
|
let pinExpiry = 0;
|
|
@@ -103,7 +124,7 @@ function startTelegramBot() {
|
|
|
103
124
|
return;
|
|
104
125
|
});
|
|
105
126
|
bot.command('clear', async (ctx) => {
|
|
106
|
-
reasoning_1.logger.clear(ctx.chat?.id
|
|
127
|
+
reasoning_1.logger.clear(`telegram_${ctx.chat?.id}`);
|
|
107
128
|
await ctx.reply("✅ AI memory has been cleared. Let's start a new chat!");
|
|
108
129
|
});
|
|
109
130
|
bot.on('message:text', async (ctx) => {
|
|
@@ -112,30 +133,103 @@ function startTelegramBot() {
|
|
|
112
133
|
return;
|
|
113
134
|
console.log(`[Telegram] Received from ${ctx.from?.first_name || 'User'}: ${text}`);
|
|
114
135
|
await ctx.replyWithChatAction('typing');
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
136
|
+
// No need for a placeholder message anymore! We use ephemeral drafts.
|
|
137
|
+
const draft_id = Math.floor(Math.random() * 100000000) + 1;
|
|
138
|
+
let buffer = '';
|
|
139
|
+
let lastDraftAt = 0;
|
|
140
|
+
let isDrafting = false;
|
|
141
|
+
const THROTTLE_MS = 100; // Native drafts can be streamed incredibly fast
|
|
142
|
+
const onChunk = async (chunk) => {
|
|
143
|
+
buffer += chunk;
|
|
144
|
+
const now = Date.now();
|
|
145
|
+
if (!isDrafting && now - lastDraftAt >= THROTTLE_MS) {
|
|
146
|
+
isDrafting = true;
|
|
118
147
|
try {
|
|
119
|
-
|
|
120
|
-
const sent = await ctx.reply(`<i>${progressText.replace(/_/g, '')}</i>`, { parse_mode: 'HTML' });
|
|
121
|
-
progressMsgId = sent.message_id;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
await ctx.api.editMessageText(ctx.chat.id, progressMsgId, `<i>${progressText.replace(/_/g, '')}</i>`, { parse_mode: 'HTML' });
|
|
125
|
-
}
|
|
148
|
+
await ctx.api.sendMessageDraft(ctx.chat.id, draft_id, formatToTelegramHTML(buffer), { parse_mode: 'HTML' });
|
|
126
149
|
}
|
|
127
150
|
catch { }
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (progressMsgId) {
|
|
131
|
-
await ctx.api.deleteMessage(ctx.chat.id, progressMsgId).catch(() => { });
|
|
151
|
+
lastDraftAt = Date.now();
|
|
152
|
+
isDrafting = false;
|
|
132
153
|
}
|
|
133
|
-
|
|
134
|
-
|
|
154
|
+
};
|
|
155
|
+
const onProgress = async (msg) => {
|
|
156
|
+
if (!isDrafting) {
|
|
157
|
+
isDrafting = true;
|
|
158
|
+
try {
|
|
159
|
+
await ctx.api.sendMessageDraft(ctx.chat.id, draft_id, `<i>${msg.replace(/_/g, '')}</i>`, { parse_mode: 'HTML' });
|
|
160
|
+
}
|
|
161
|
+
catch { }
|
|
162
|
+
isDrafting = false;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
try {
|
|
166
|
+
const response = await (0, reasoning_1.processUserInputStream)(text, onChunk, onProgress, `telegram_${ctx.chat?.id}`);
|
|
167
|
+
// Finalize by sending the permanent message (which replaces the draft)
|
|
168
|
+
let replyMarkup = undefined;
|
|
169
|
+
if (/Reply \*\*Yes\*\*/i.test(response) && /\*\*No\*\* to cancel/i.test(response)) {
|
|
170
|
+
replyMarkup = new grammy_1.InlineKeyboard()
|
|
171
|
+
.text('✅ Approve', 'tx_approve')
|
|
172
|
+
.text('❌ Reject', 'tx_reject');
|
|
173
|
+
}
|
|
174
|
+
await ctx.reply(formatToTelegramHTML(response), { parse_mode: 'HTML', reply_markup: replyMarkup }).catch((e) => {
|
|
175
|
+
console.error("[Telegram] CRITICAL: ctx.reply failed in text handler:", e.message);
|
|
176
|
+
});
|
|
135
177
|
}
|
|
136
178
|
catch (error) {
|
|
137
179
|
console.error('[Telegram] Error processing message:', error);
|
|
138
|
-
await ctx.reply('❌ Sorry, I encountered an error while processing your message.');
|
|
180
|
+
await ctx.reply('❌ Sorry, I encountered an error while processing your message.', {}).catch(() => { });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
bot.on('callback_query:data', async (ctx) => {
|
|
184
|
+
const data = ctx.callbackQuery.data;
|
|
185
|
+
if (data === 'tx_approve' || data === 'tx_reject') {
|
|
186
|
+
await ctx.answerCallbackQuery().catch(() => { });
|
|
187
|
+
await ctx.editMessageReplyMarkup(undefined).catch(() => { });
|
|
188
|
+
const simulatedText = data === 'tx_approve' ? 'yes' : 'no';
|
|
189
|
+
console.log(`[Telegram] User clicked ${simulatedText.toUpperCase()} via Inline Keyboard`);
|
|
190
|
+
if (!ctx.chat)
|
|
191
|
+
return;
|
|
192
|
+
await ctx.replyWithChatAction('typing');
|
|
193
|
+
const draft_id = Math.floor(Math.random() * 100000000) + 1;
|
|
194
|
+
let buffer = '';
|
|
195
|
+
let lastDraftAt = 0;
|
|
196
|
+
let isDrafting = false;
|
|
197
|
+
const onChunk = async (chunk) => {
|
|
198
|
+
buffer += chunk;
|
|
199
|
+
const now = Date.now();
|
|
200
|
+
if (!isDrafting && now - lastDraftAt >= 100) {
|
|
201
|
+
isDrafting = true;
|
|
202
|
+
try {
|
|
203
|
+
await ctx.api.sendMessageDraft(ctx.chat.id, draft_id, formatToTelegramHTML(buffer), { parse_mode: 'HTML' });
|
|
204
|
+
}
|
|
205
|
+
catch { }
|
|
206
|
+
lastDraftAt = Date.now();
|
|
207
|
+
isDrafting = false;
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
const onProgress = async (msg) => {
|
|
211
|
+
if (!isDrafting) {
|
|
212
|
+
isDrafting = true;
|
|
213
|
+
try {
|
|
214
|
+
await ctx.api.sendMessageDraft(ctx.chat.id, draft_id, `<i>${msg.replace(/_/g, '')}</i>`, { parse_mode: 'HTML' });
|
|
215
|
+
}
|
|
216
|
+
catch { }
|
|
217
|
+
isDrafting = false;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
try {
|
|
221
|
+
const response = await (0, reasoning_1.processUserInputStream)(simulatedText, onChunk, onProgress, `telegram_${ctx.chat.id}`);
|
|
222
|
+
let replyMarkup = undefined;
|
|
223
|
+
if (/Reply \*\*Yes\*\*/i.test(response) && /\*\*No\*\* to cancel/i.test(response)) {
|
|
224
|
+
replyMarkup = new grammy_1.InlineKeyboard().text('✅ Approve', 'tx_approve').text('❌ Reject', 'tx_reject');
|
|
225
|
+
}
|
|
226
|
+
await ctx.reply(formatToTelegramHTML(response), { parse_mode: 'HTML', reply_markup: replyMarkup }).catch((e) => {
|
|
227
|
+
console.error("[Telegram] CRITICAL: ctx.reply failed in callback:", e.message);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
await ctx.reply('❌ Sorry, I encountered an error.', {}).catch(() => { });
|
|
232
|
+
}
|
|
139
233
|
}
|
|
140
234
|
});
|
|
141
235
|
bot.on('message:document', async (ctx) => {
|
|
@@ -183,7 +277,9 @@ function startTelegramBot() {
|
|
|
183
277
|
bot.catch((err) => {
|
|
184
278
|
console.error('[Telegram] Grammy error:', err);
|
|
185
279
|
});
|
|
186
|
-
runnerInstance = (0, runner_1.run)(bot
|
|
280
|
+
runnerInstance = (0, runner_1.run)(bot, {
|
|
281
|
+
runner: { silent: true }
|
|
282
|
+
});
|
|
187
283
|
if (isPaired) {
|
|
188
284
|
console.log('🤖 Telegram Bot is running and securely listening for your messages...');
|
|
189
285
|
}
|
|
@@ -36,11 +36,17 @@ class EpisodicMemoryDB {
|
|
|
36
36
|
CREATE TABLE IF NOT EXISTS user_personas (
|
|
37
37
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
38
38
|
trait TEXT UNIQUE NOT NULL,
|
|
39
|
+
category TEXT DEFAULT 'general',
|
|
39
40
|
confidence REAL DEFAULT 0.1,
|
|
40
41
|
source TEXT,
|
|
41
42
|
lastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
42
43
|
);
|
|
43
44
|
`);
|
|
45
|
+
// Migration: add category column if missing (for older DBs)
|
|
46
|
+
try {
|
|
47
|
+
this.db.prepare('ALTER TABLE user_personas ADD COLUMN category TEXT DEFAULT \'general\'').run();
|
|
48
|
+
}
|
|
49
|
+
catch { }
|
|
44
50
|
}
|
|
45
51
|
addCandidateFact(fact, confidenceScore = 0.5, category = 'general', ruleType = 'observation', keyTopic) {
|
|
46
52
|
if (keyTopic) {
|
|
@@ -93,6 +99,10 @@ class EpisodicMemoryDB {
|
|
|
93
99
|
const stmt = this.db.prepare('DELETE FROM episodic_memories');
|
|
94
100
|
stmt.run();
|
|
95
101
|
}
|
|
102
|
+
clearAllPersonas() {
|
|
103
|
+
const stmt = this.db.prepare('DELETE FROM user_personas');
|
|
104
|
+
stmt.run();
|
|
105
|
+
}
|
|
96
106
|
close() {
|
|
97
107
|
try {
|
|
98
108
|
this.db.close();
|
|
@@ -100,7 +110,11 @@ class EpisodicMemoryDB {
|
|
|
100
110
|
catch { }
|
|
101
111
|
}
|
|
102
112
|
// --- PERSONA MODELING ---
|
|
103
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Legacy method: upsert by exact trait string.
|
|
115
|
+
* Kept for backward compatibility but prefer upsertPersonaByCategory.
|
|
116
|
+
*/
|
|
117
|
+
updatePersonaTrait(trait, confidence = 0.5, source = 'nyx_daemon') {
|
|
104
118
|
const existing = this.db.prepare('SELECT id, confidence FROM user_personas WHERE trait = ?').get(trait);
|
|
105
119
|
if (existing) {
|
|
106
120
|
const newConfidence = Math.min(1.0, existing.confidence + (confidence * 0.2));
|
|
@@ -108,14 +122,44 @@ class EpisodicMemoryDB {
|
|
|
108
122
|
stmt.run(newConfidence, source, existing.id);
|
|
109
123
|
}
|
|
110
124
|
else {
|
|
111
|
-
const stmt = this.db.prepare('INSERT INTO user_personas (trait, confidence, source) VALUES (?, ?, ?)');
|
|
112
|
-
stmt.run(trait, confidence, source);
|
|
125
|
+
const stmt = this.db.prepare('INSERT INTO user_personas (trait, category, confidence, source) VALUES (?, ?, ?, ?)');
|
|
126
|
+
stmt.run(trait, 'general', confidence, source);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Category-based upsert: each category (language, tone, trading_style, behavior)
|
|
131
|
+
* has exactly ONE row in user_personas, identified by category.
|
|
132
|
+
* This ensures confidence accumulates correctly across audit cycles
|
|
133
|
+
* instead of creating duplicate rows with slightly different phrasing.
|
|
134
|
+
*/
|
|
135
|
+
upsertPersonaByCategory(category, value, confidence = 0.5, source = 'nyx_daemon') {
|
|
136
|
+
if (!value || !value.trim())
|
|
137
|
+
return;
|
|
138
|
+
const existing = this.db.prepare('SELECT id, confidence FROM user_personas WHERE category = ?').get(category);
|
|
139
|
+
if (existing) {
|
|
140
|
+
const newConfidence = Math.min(1.0, existing.confidence + (confidence * 0.2));
|
|
141
|
+
this.db.prepare('UPDATE user_personas SET trait = ?, confidence = ?, source = ?, lastUpdated = CURRENT_TIMESTAMP WHERE id = ?').run(value.trim(), newConfidence, source, existing.id);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
this.db.prepare('INSERT INTO user_personas (trait, category, confidence, source) VALUES (?, ?, ?, ?)').run(value.trim(), category, confidence, source);
|
|
113
145
|
}
|
|
114
146
|
}
|
|
115
147
|
getPersonas() {
|
|
116
148
|
const stmt = this.db.prepare('SELECT * FROM user_personas ORDER BY confidence DESC');
|
|
117
149
|
return stmt.all();
|
|
118
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Get personas filtered by minimum confidence threshold.
|
|
153
|
+
*/
|
|
154
|
+
getStrongPersonas(minConfidence = 0.5) {
|
|
155
|
+
const stmt = this.db.prepare('SELECT * FROM user_personas WHERE confidence >= ? ORDER BY confidence DESC');
|
|
156
|
+
return stmt.all(minConfidence);
|
|
157
|
+
}
|
|
158
|
+
deletePersonaByTrait(keyword) {
|
|
159
|
+
const stmt = this.db.prepare('DELETE FROM user_personas WHERE trait LIKE ?');
|
|
160
|
+
const result = stmt.run(`%${keyword}%`);
|
|
161
|
+
return result.changes || 0;
|
|
162
|
+
}
|
|
119
163
|
}
|
|
120
164
|
exports.EpisodicMemoryDB = EpisodicMemoryDB;
|
|
121
165
|
// Singleton instance
|
|
@@ -81,6 +81,32 @@ class Logger {
|
|
|
81
81
|
custom_rules TEXT,
|
|
82
82
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
83
83
|
)
|
|
84
|
+
`);
|
|
85
|
+
// V4: Transaction Persistence
|
|
86
|
+
this.db.exec(`
|
|
87
|
+
CREATE TABLE IF NOT EXISTS pending_transactions (
|
|
88
|
+
id TEXT PRIMARY KEY,
|
|
89
|
+
type TEXT NOT NULL,
|
|
90
|
+
chain_name TEXT NOT NULL,
|
|
91
|
+
details TEXT NOT NULL,
|
|
92
|
+
status TEXT NOT NULL,
|
|
93
|
+
result TEXT,
|
|
94
|
+
nonce TEXT,
|
|
95
|
+
created_at INTEGER NOT NULL
|
|
96
|
+
)
|
|
97
|
+
`);
|
|
98
|
+
this.db.exec(`
|
|
99
|
+
CREATE TABLE IF NOT EXISTS pending_withdrawals (
|
|
100
|
+
id TEXT PRIMARY KEY,
|
|
101
|
+
l2_tx_hash TEXT NOT NULL,
|
|
102
|
+
l1_chain TEXT NOT NULL,
|
|
103
|
+
l2_chain TEXT NOT NULL,
|
|
104
|
+
portal_address TEXT NOT NULL,
|
|
105
|
+
user_address TEXT NOT NULL,
|
|
106
|
+
amount TEXT NOT NULL,
|
|
107
|
+
status TEXT NOT NULL,
|
|
108
|
+
created_at INTEGER NOT NULL
|
|
109
|
+
)
|
|
84
110
|
`);
|
|
85
111
|
// Ensure session_id exists for older DBs
|
|
86
112
|
try {
|
|
@@ -158,7 +184,7 @@ class Logger {
|
|
|
158
184
|
ORDER BY s.timestamp DESC
|
|
159
185
|
`).all(term, term);
|
|
160
186
|
}
|
|
161
|
-
getHistory(sessionId, limit =
|
|
187
|
+
getHistory(sessionId, limit = 70) {
|
|
162
188
|
let rows;
|
|
163
189
|
// Phase 2: Sliding Window Algorithm (LLM Context Limit)
|
|
164
190
|
// Fetch only the last X messages, then order them chronologically
|
|
@@ -198,13 +224,45 @@ class Logger {
|
|
|
198
224
|
return entry;
|
|
199
225
|
});
|
|
200
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Returns the N most recent messages across ALL sessions (including Telegram, Discord, and NULL sessions).
|
|
229
|
+
* Used by NyxDaemon to analyze conversation history from every channel.
|
|
230
|
+
*/
|
|
231
|
+
getRecentMessagesAllSessions(limit = 30) {
|
|
232
|
+
const rows = this.db.prepare(`
|
|
233
|
+
SELECT * FROM (
|
|
234
|
+
SELECT role, content, name, tool_call_id, tool_calls, session_id, id
|
|
235
|
+
FROM messages
|
|
236
|
+
ORDER BY id DESC LIMIT ?
|
|
237
|
+
) ORDER BY id ASC
|
|
238
|
+
`).all(limit);
|
|
239
|
+
return rows.map((row) => {
|
|
240
|
+
const entry = {
|
|
241
|
+
role: row.role,
|
|
242
|
+
content: row.content,
|
|
243
|
+
};
|
|
244
|
+
if (row.name)
|
|
245
|
+
entry.name = row.name;
|
|
246
|
+
if (row.tool_call_id)
|
|
247
|
+
entry.tool_call_id = row.tool_call_id;
|
|
248
|
+
if (row.tool_calls)
|
|
249
|
+
entry.tool_calls = JSON.parse(row.tool_calls);
|
|
250
|
+
if (row.session_id)
|
|
251
|
+
entry.session_id = row.session_id;
|
|
252
|
+
return entry;
|
|
253
|
+
});
|
|
254
|
+
}
|
|
201
255
|
addEntry(entry, sessionId) {
|
|
202
256
|
if (sessionId) {
|
|
203
257
|
// Auto-create session if it doesn't exist (e.g. for Telegram integration)
|
|
204
258
|
try {
|
|
205
259
|
const sessionExists = this.db.prepare('SELECT 1 FROM sessions WHERE id = ?').get(sessionId);
|
|
206
260
|
if (!sessionExists) {
|
|
207
|
-
|
|
261
|
+
let title = 'New Session';
|
|
262
|
+
if (sessionId.startsWith('telegram_'))
|
|
263
|
+
title = 'Telegram Chat';
|
|
264
|
+
else if (sessionId.startsWith('discord_'))
|
|
265
|
+
title = 'Discord Chat';
|
|
208
266
|
this.db.prepare('INSERT INTO sessions (id, title) VALUES (?, ?)').run(sessionId, title);
|
|
209
267
|
}
|
|
210
268
|
}
|
|
@@ -294,6 +352,66 @@ class Logger {
|
|
|
294
352
|
const result = this.db.prepare(`UPDATE limit_orders SET status = 'ACTIVE' WHERE id = ?`).run(orderId);
|
|
295
353
|
return result.changes > 0;
|
|
296
354
|
}
|
|
355
|
+
// V4: Transaction Persistence Methods
|
|
356
|
+
savePendingTransaction(tx) {
|
|
357
|
+
this.db.prepare(`
|
|
358
|
+
INSERT INTO pending_transactions (id, type, chain_name, details, status, result, nonce, created_at)
|
|
359
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
360
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
361
|
+
status = excluded.status,
|
|
362
|
+
result = excluded.result,
|
|
363
|
+
nonce = excluded.nonce
|
|
364
|
+
`).run(tx.id, tx.type, tx.chainName, JSON.stringify(tx.details), tx.status, tx.result || null, tx.nonce || null, tx.createdAt || Date.now());
|
|
365
|
+
}
|
|
366
|
+
getPendingTransactions() {
|
|
367
|
+
const rows = this.db.prepare(`SELECT * FROM pending_transactions WHERE status = 'pending'`).all();
|
|
368
|
+
return rows.map(r => ({
|
|
369
|
+
id: r.id,
|
|
370
|
+
type: r.type,
|
|
371
|
+
chainName: r.chain_name,
|
|
372
|
+
details: JSON.parse(r.details),
|
|
373
|
+
status: r.status,
|
|
374
|
+
result: r.result,
|
|
375
|
+
nonce: r.nonce,
|
|
376
|
+
createdAt: r.created_at
|
|
377
|
+
}));
|
|
378
|
+
}
|
|
379
|
+
getTransaction(id) {
|
|
380
|
+
const r = this.db.prepare(`SELECT * FROM pending_transactions WHERE id = ?`).get(id);
|
|
381
|
+
if (!r)
|
|
382
|
+
return undefined;
|
|
383
|
+
return {
|
|
384
|
+
id: r.id,
|
|
385
|
+
type: r.type,
|
|
386
|
+
chainName: r.chain_name,
|
|
387
|
+
details: JSON.parse(r.details),
|
|
388
|
+
status: r.status,
|
|
389
|
+
result: r.result,
|
|
390
|
+
nonce: r.nonce,
|
|
391
|
+
createdAt: r.created_at
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
savePendingWithdrawal(w) {
|
|
395
|
+
this.db.prepare(`
|
|
396
|
+
INSERT INTO pending_withdrawals (id, l2_tx_hash, l1_chain, l2_chain, portal_address, user_address, amount, status, created_at)
|
|
397
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
398
|
+
ON CONFLICT(id) DO UPDATE SET status = excluded.status
|
|
399
|
+
`).run(w.id, w.l2TxHash, w.l1Chain, w.l2Chain, w.portalAddress, w.userAddress, w.amount, w.status, w.createdAt || Date.now());
|
|
400
|
+
}
|
|
401
|
+
getPendingWithdrawals() {
|
|
402
|
+
const rows = this.db.prepare(`SELECT * FROM pending_withdrawals WHERE status != 'COMPLETED'`).all();
|
|
403
|
+
return rows.map(r => ({
|
|
404
|
+
id: r.id,
|
|
405
|
+
l2TxHash: r.l2_tx_hash,
|
|
406
|
+
l1Chain: r.l1_chain,
|
|
407
|
+
l2Chain: r.l2_chain,
|
|
408
|
+
portalAddress: r.portal_address,
|
|
409
|
+
userAddress: r.user_address,
|
|
410
|
+
amount: r.amount,
|
|
411
|
+
status: r.status,
|
|
412
|
+
createdAt: r.created_at
|
|
413
|
+
}));
|
|
414
|
+
}
|
|
297
415
|
}
|
|
298
416
|
exports.Logger = Logger;
|
|
299
417
|
exports.logger = new Logger();
|
|
@@ -38,18 +38,31 @@ class PromotionEngine {
|
|
|
38
38
|
// Deduplicate arrays
|
|
39
39
|
const uniquePermanent = [...new Set(permanentPreferences)];
|
|
40
40
|
const uniqueRecent = [...new Set(recentObservations)];
|
|
41
|
-
// 4.
|
|
42
|
-
|
|
41
|
+
// 4. Fetch Persona Traits
|
|
42
|
+
const personas = episodic_1.episodicDB.getStrongPersonas(0.4);
|
|
43
|
+
const personaStrings = [];
|
|
44
|
+
for (const p of personas) {
|
|
45
|
+
personaStrings.push(`- [${p.category.toUpperCase()}] ${p.trait}`);
|
|
46
|
+
}
|
|
47
|
+
// 5. Rewrite user.md (The Golden Profile)
|
|
48
|
+
this.rewriteUserProfile(uniquePermanent, uniqueRecent, personaStrings);
|
|
43
49
|
}
|
|
44
50
|
catch (error) {
|
|
45
51
|
console.error('[PromotionEngine] Error running promotion engine:', error);
|
|
46
52
|
}
|
|
47
53
|
}
|
|
48
|
-
static rewriteUserProfile(permanent, recent) {
|
|
54
|
+
static rewriteUserProfile(permanent, recent, personas = []) {
|
|
49
55
|
const userMdPath = (0, paths_1.getPath)('user.md');
|
|
50
56
|
let newContent = `Write custom instructions, special rules, user profiles, or the persona you want for Nyxora AI in this file.\n\n`;
|
|
51
57
|
newContent += `<!-- AUTOMANAGED BY PROMOTION ENGINE. MANUAL EDITS MAY BE OVERWRITTEN -->\n\n`;
|
|
52
|
-
newContent += `#
|
|
58
|
+
newContent += `# User Persona & Identity\n`;
|
|
59
|
+
if (personas.length === 0) {
|
|
60
|
+
newContent += `*(No specific persona traits identified yet)*\n`;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
newContent += personas.join('\n') + '\n';
|
|
64
|
+
}
|
|
65
|
+
newContent += `\n# Permanent Preferences\n`;
|
|
53
66
|
if (permanent.length === 0) {
|
|
54
67
|
newContent += `*(No permanent preferences recorded yet)*\n`;
|
|
55
68
|
}
|
|
@@ -64,7 +77,7 @@ class PromotionEngine {
|
|
|
64
77
|
newContent += recent.join('\n') + '\n';
|
|
65
78
|
}
|
|
66
79
|
fs_1.default.writeFileSync(userMdPath, newContent, 'utf-8');
|
|
67
|
-
console.log(`[PromotionEngine] user.md successfully synchronized with Layer 2 Episodic Memory.`);
|
|
80
|
+
console.log(`[PromotionEngine] user.md successfully synchronized with Layer 2 Episodic Memory and Personas.`);
|
|
68
81
|
}
|
|
69
82
|
}
|
|
70
83
|
exports.PromotionEngine = PromotionEngine;
|
|
@@ -161,6 +161,16 @@ class AgentSkills {
|
|
|
161
161
|
if (!fs_1.default.existsSync(scriptPath)) {
|
|
162
162
|
throw new Error(`Execution script not found for skill '${name}' at path: ${scriptPath}`);
|
|
163
163
|
}
|
|
164
|
+
// Automatically load .env for the skill if it exists
|
|
165
|
+
const envPath = path_1.default.join(this.skillsDir, name, '.env');
|
|
166
|
+
if (fs_1.default.existsSync(envPath)) {
|
|
167
|
+
try {
|
|
168
|
+
require('dotenv').config({ path: envPath });
|
|
169
|
+
}
|
|
170
|
+
catch (e) {
|
|
171
|
+
console.warn(`[AgentSkills] Failed to load .env for skill '${name}':`, e);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
164
174
|
try {
|
|
165
175
|
// Dynamic import of the TS/JS module
|
|
166
176
|
const module = await Promise.resolve(`${scriptPath}`).then(s => __importStar(require(s)));
|
|
@@ -5,7 +5,7 @@ const googleWorkspace_1 = require("../skills/googleWorkspace");
|
|
|
5
5
|
class GoogleWorkspacePlugin {
|
|
6
6
|
name = 'GoogleWorkspacePlugin';
|
|
7
7
|
description = 'Google Workspace operations including Gmail, Calendar, Docs, and Sheets.';
|
|
8
|
-
version = '1.0.
|
|
8
|
+
version = '1.0.1';
|
|
9
9
|
tools = [
|
|
10
10
|
googleWorkspace_1.readGmailInboxToolDefinition,
|
|
11
11
|
googleWorkspace_1.listCalendarEventsToolDefinition,
|
|
@@ -10,7 +10,7 @@ const forgetMemory_1 = require("../skills/forgetMemory");
|
|
|
10
10
|
class SystemCorePlugin {
|
|
11
11
|
name = 'SystemCorePlugin';
|
|
12
12
|
description = 'Core system identity, profile, and task scheduling operations.';
|
|
13
|
-
version = '1.0.
|
|
13
|
+
version = '1.0.1';
|
|
14
14
|
tools = [
|
|
15
15
|
updateProfile_1.updateProfileToolDefinition,
|
|
16
16
|
updateIdentity_1.updateIdentityToolDefinition,
|
|
@@ -5,7 +5,7 @@ const createAgentSkill_1 = require("../skills/createAgentSkill");
|
|
|
5
5
|
class SystemExternalPlugin {
|
|
6
6
|
name = 'SystemExternalPlugin';
|
|
7
7
|
description = 'Provides tools for creating and managing third-party external agent skills.';
|
|
8
|
-
version = '1.0.
|
|
8
|
+
version = '1.0.1';
|
|
9
9
|
tools = [
|
|
10
10
|
createAgentSkill_1.createAgentSkillToolDefinition
|
|
11
11
|
];
|
|
@@ -25,7 +25,7 @@ const installPluginDefinition = {
|
|
|
25
25
|
class SystemPluginInstallerPlugin {
|
|
26
26
|
name = 'SystemPluginInstallerPlugin';
|
|
27
27
|
description = 'Autonomous package manager for installing and auto-healing dynamic plugins.';
|
|
28
|
-
version = '1.0.
|
|
28
|
+
version = '1.0.1';
|
|
29
29
|
tools = [installPluginDefinition];
|
|
30
30
|
handlers = {
|
|
31
31
|
['install_plugin']: async (args) => {
|
|
@@ -6,7 +6,7 @@ const notionWorkspace_1 = require("../skills/notionWorkspace");
|
|
|
6
6
|
class SystemSocialPlugin {
|
|
7
7
|
name = 'SystemSocialPlugin';
|
|
8
8
|
description = 'Social media and external workspace operations (Twitter, Notion).';
|
|
9
|
-
version = '1.0.
|
|
9
|
+
version = '1.0.1';
|
|
10
10
|
tools = [
|
|
11
11
|
xManager_1.xManagerToolDefinition,
|
|
12
12
|
notionWorkspace_1.notionWorkspaceToolDefinition
|
|
@@ -9,7 +9,7 @@ const audioTranscribe_1 = require("../skills/audioTranscribe");
|
|
|
9
9
|
class SystemWebPlugin {
|
|
10
10
|
name = 'SystemWebPlugin';
|
|
11
11
|
description = 'Web browsing, searching, and media analysis operations.';
|
|
12
|
-
version = '1.0.
|
|
12
|
+
version = '1.0.1';
|
|
13
13
|
tools = [
|
|
14
14
|
browseWeb_1.browseWebsiteToolDefinition,
|
|
15
15
|
searchWeb_1.searchWebToolDefinition,
|
|
@@ -11,7 +11,7 @@ const createCognitiveSkill_1 = require("../skills/createCognitiveSkill");
|
|
|
11
11
|
class SystemWorkspacePlugin {
|
|
12
12
|
name = 'SystemWorkspacePlugin';
|
|
13
13
|
description = 'Local system operations including file management, terminal execution, and Git.';
|
|
14
|
-
version = '1.0.
|
|
14
|
+
version = '1.0.1';
|
|
15
15
|
tools = [
|
|
16
16
|
readFile_1.readLocalFileToolDefinition,
|
|
17
17
|
writeFile_1.writeLocalFileToolDefinition,
|
|
@@ -31,8 +31,8 @@ class SystemWorkspacePlugin {
|
|
|
31
31
|
['edit_local_file']: async (args) => {
|
|
32
32
|
return await (0, editFile_1.editLocalFile)(args.filePath, args.searchString, args.replacementString);
|
|
33
33
|
},
|
|
34
|
-
['
|
|
35
|
-
return await (0, generateExcel_1.generateExcelFile)(args.data, args.
|
|
34
|
+
['generate_excel_file']: async (args) => {
|
|
35
|
+
return await (0, generateExcel_1.generateExcelFile)(args.data, args.filePath);
|
|
36
36
|
},
|
|
37
37
|
['run_terminal_command']: async (args) => {
|
|
38
38
|
return await (0, executeShell_1.runTerminalCommand)(args.command);
|
|
@@ -5,7 +5,7 @@ const skillExtractor_1 = require("../skillExtractor");
|
|
|
5
5
|
const reasoning_1 = require("../../agent/reasoning");
|
|
6
6
|
class CreateSkillPlugin {
|
|
7
7
|
name = 'CreateSkill';
|
|
8
|
-
version = '1.0.
|
|
8
|
+
version = '1.0.1';
|
|
9
9
|
description = 'Autonomously extracts and creates skills for Nyxora.';
|
|
10
10
|
tools = [
|
|
11
11
|
{
|
|
@@ -30,11 +30,22 @@ User Intent / Logic: ${userIntent}
|
|
|
30
30
|
Chat Traces (if any):
|
|
31
31
|
${historyTraces.join('\n')}
|
|
32
32
|
|
|
33
|
-
The SKILL.md must contain a YAML frontmatter block
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
The SKILL.md must contain a YAML frontmatter block exactly following this structure:
|
|
34
|
+
---
|
|
35
|
+
name: ${safeName}
|
|
36
|
+
version: 1.0.0
|
|
37
|
+
description: <Your generated description>
|
|
38
|
+
parameters:
|
|
39
|
+
type: object
|
|
40
|
+
properties:
|
|
41
|
+
param1:
|
|
42
|
+
type: string
|
|
43
|
+
description: ...
|
|
44
|
+
required:
|
|
45
|
+
- param1
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
CRITICAL: The 'required' array MUST be indented exactly inside the 'parameters' block as shown above. Do NOT put 'required' at the root level of the YAML.
|
|
38
49
|
|
|
39
50
|
Do NOT write anything outside the frontmatter except an optional markdown description below it.
|
|
40
51
|
Output ONLY the raw SKILL.md content.`;
|
|
@@ -23,13 +23,15 @@ exports.forgetMemoryToolDefinition = {
|
|
|
23
23
|
};
|
|
24
24
|
async function forgetMemory(keyword) {
|
|
25
25
|
try {
|
|
26
|
-
const
|
|
27
|
-
|
|
26
|
+
const memoryChanges = episodic_1.episodicDB.deleteMemoryByFact(keyword);
|
|
27
|
+
const personaChanges = episodic_1.episodicDB.deletePersonaByTrait(keyword);
|
|
28
|
+
const totalChanges = memoryChanges + personaChanges;
|
|
29
|
+
if (totalChanges > 0) {
|
|
28
30
|
await promotionEngine_1.PromotionEngine.runPromotionAndDecay();
|
|
29
|
-
return `[Success] Deleted ${
|
|
31
|
+
return `[Success] Deleted ${memoryChanges} memory record(s) and ${personaChanges} persona trait(s) containing '${keyword}'. Profile synchronized.`;
|
|
30
32
|
}
|
|
31
33
|
else {
|
|
32
|
-
return `[Info] No memories found containing the keyword '${keyword}'.`;
|
|
34
|
+
return `[Info] No memories or persona traits found containing the keyword '${keyword}'.`;
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
catch (error) {
|