obol-ai 0.3.21 → 0.3.23

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 CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.3.22
2
+ - update changelog
3
+ - fix soul backup version number to use evolutionNumber
4
+
1
5
  ## 0.3.21
2
6
  - update changelog
3
7
  - store one soul row per evolution in supabase
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obol-ai",
3
- "version": "0.3.21",
3
+ "version": "0.3.23",
4
4
  "description": "Self-evolving AI assistant that learns, remembers, and acts on its own. Persistent vector memory, self-rewriting personality, proactive heartbeats.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -188,6 +188,7 @@ async function manageUsers(cfg, saveConfig) {
188
188
  if (removeId !== null) {
189
189
  const idx = currentUsers.indexOf(removeId);
190
190
  if (idx !== -1) currentUsers.splice(idx, 1);
191
+ if (cfg.users) delete cfg.users[String(removeId)];
191
192
  console.log(` ✅ Removed ${removeId}`);
192
193
  console.log(` ⚠️ Workspace at ${getUserDir(removeId)} was NOT deleted (remove manually if needed)`);
193
194
  }
@@ -351,7 +351,7 @@ Fix the scripts. Tests define correct behavior.`
351
351
  fs.writeFileSync(soulPath, result.soul);
352
352
  if (supabaseConfig) {
353
353
  const { backup } = require('../soul');
354
- backup(supabaseConfig, `soul-v${state.evolutionCount}`, result.soul).catch(e =>
354
+ backup(supabaseConfig, `soul-v${evolutionNumber}`, result.soul).catch(e =>
355
355
  console.error('[evolve] Soul backup failed:', e.message)
356
356
  );
357
357
  }
@@ -1,4 +1,5 @@
1
1
  const { buildStatusHtml, formatToolCall } = require('../status');
2
+ const { markdownToTelegramHtml } = require('../telegram/utils');
2
3
 
3
4
  const MAX_CONCURRENT_TASKS = 3;
4
5
 
@@ -160,27 +161,22 @@ function formatDuration(seconds) {
160
161
 
161
162
  async function sendLong(ctx, text) {
162
163
  if (!text?.trim()) return;
163
- if (text.length <= 4096) {
164
- await ctx.reply(text, { parse_mode: 'HTML' }).catch(() =>
165
- ctx.reply(text)
166
- );
164
+ const html = markdownToTelegramHtml(text);
165
+ if (html.length <= 4096) {
166
+ await ctx.reply(html, { parse_mode: 'HTML' }).catch(() => ctx.reply(text));
167
167
  return;
168
168
  }
169
169
 
170
- let remaining = text;
170
+ let remaining = html;
171
171
  while (remaining.length > 0) {
172
172
  if (remaining.length <= 4096) {
173
- await ctx.reply(remaining, { parse_mode: 'HTML' }).catch(() =>
174
- ctx.reply(remaining)
175
- );
173
+ await ctx.reply(remaining, { parse_mode: 'HTML' }).catch(() => ctx.reply(remaining));
176
174
  break;
177
175
  }
178
176
  let splitAt = remaining.lastIndexOf('\n', 4096);
179
177
  if (splitAt === -1 || splitAt < 2000) splitAt = 4096;
180
178
  const chunk = remaining.substring(0, splitAt);
181
- await ctx.reply(chunk, { parse_mode: 'HTML' }).catch(() =>
182
- ctx.reply(chunk)
183
- );
179
+ await ctx.reply(chunk, { parse_mode: 'HTML' }).catch(() => ctx.reply(chunk));
184
180
  remaining = remaining.substring(splitAt).trimStart();
185
181
  }
186
182
  }
@@ -103,6 +103,7 @@ function createBot(telegramConfig, config) {
103
103
  { command: 'options', description: 'Toggle optional features on/off' },
104
104
  { command: 'topics', description: 'Edit news topics' },
105
105
  { command: 'stop', description: 'Stop the current request' },
106
+ { command: 'restart', description: 'Restart the bot (pm2)' },
106
107
  { command: 'upgrade', description: 'Check for updates and upgrade' },
107
108
  { command: 'help', description: 'Show available commands' },
108
109
  ]).catch(() => {});
@@ -168,6 +168,16 @@ Summarize what was cleaned and secrets migrated.`);
168
168
  }
169
169
  });
170
170
 
171
+ bot.command('restart', async (ctx) => {
172
+ if (!ctx.from) return;
173
+ await ctx.reply('🔄 Restarting...');
174
+ try {
175
+ execSync('pm2 restart obol', { encoding: 'utf-8', timeout: 15000 });
176
+ } catch (e) {
177
+ await ctx.reply(`⚠️ Restart failed: ${e.message.substring(0, 200)}`);
178
+ }
179
+ });
180
+
171
181
  bot.command('toolimit', async (ctx) => {
172
182
  if (!ctx.from) return;
173
183
  const args = ctx.message.text.split(' ').slice(1);
@@ -54,6 +54,7 @@ function register(bot, config) {
54
54
  /verbose — Toggle verbose mode on/off
55
55
  /toolimit — View or set max tool iterations
56
56
  /stop — Stop the current request
57
+ /restart — Restart the bot
57
58
  /upgrade — Check for updates and upgrade
58
59
  /help — This message`);
59
60
  });
@@ -10,7 +10,7 @@ const VERBOSE_FLUSH_MS = 2000;
10
10
  async function sendTtsVoiceSummary(ctx, tenant, responseText) {
11
11
  const fs = require('fs');
12
12
  const { InputFile } = require('grammy');
13
- const tts = require('../../tts');
13
+ const tts = require('../../media/tts');
14
14
 
15
15
  const ttsConfig = tenant.toolPrefs.get('text_to_speech')?.config || {};
16
16
  const voice = ttsConfig.voice || 'en-US-JennyNeural';