obol-ai 0.3.36 → 0.3.37

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.37
2
+ - changelog
3
+ - fix media group race condition — buffer before download
4
+
1
5
  ## 0.3.36
2
6
  - save media assets instantly in date-based folders
3
7
  - fix agentic event raw JSON output and update_event wiping instructions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obol-ai",
3
- "version": "0.3.36",
3
+ "version": "0.3.37",
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": {
@@ -9,7 +9,7 @@ const TEXT_BUFFER_GAP_MS = 1500;
9
9
  const TEXT_BUFFER_MAX_PARTS = 12;
10
10
  const TEXT_BUFFER_MAX_CHARS = 50000;
11
11
  const TEXT_BUFFER_THRESHOLD = 4000;
12
- const MEDIA_GROUP_DELAY_MS = 500;
12
+ const MEDIA_GROUP_DELAY_MS = 5000;
13
13
  const MAX_MEDIA_SIZE = 50 * 1024 * 1024;
14
14
  const TERM_SEP = '━'.repeat(TERM_WIDTH);
15
15
 
@@ -16,6 +16,29 @@ async function downloadMediaItem(ctx, fileInfo, telegramToken) {
16
16
  return { buffer, filename, fileInfo, caption: ctx.message.caption || '' };
17
17
  }
18
18
 
19
+ async function downloadAndProcess(ctx, entries, deps, token) {
20
+ const userId = ctx.from.id;
21
+ const userDir = ensureUserDir(userId);
22
+ const tz = getUserTimezone(deps.config, userId);
23
+ const today = new Date().toLocaleDateString('en-CA', { timeZone: tz });
24
+ const assetsDir = path.join(userDir, 'assets', today);
25
+
26
+ const items = (await Promise.all(
27
+ entries.map(({ ctx: entryCtx, fileInfo }) =>
28
+ downloadMediaItem(entryCtx, fileInfo, token).then(item => {
29
+ if (item) item.savedPath = media.saveFile(item.buffer, assetsDir, item.filename);
30
+ return item;
31
+ }).catch(e => {
32
+ console.error('Media download error:', e.message);
33
+ return null;
34
+ })
35
+ )
36
+ )).filter(Boolean);
37
+
38
+ if (items.length === 0) return;
39
+ await processMediaItems(ctx, items, deps);
40
+ }
41
+
19
42
  async function processMediaItems(ctx, items, { config, allowedUsers, bot, createAsk }) {
20
43
  if (!ctx.from) return;
21
44
  const userId = ctx.from.id;
@@ -154,38 +177,26 @@ function registerMediaHandler(bot, telegramConfig, deps) {
154
177
  return;
155
178
  }
156
179
 
157
- const item = await downloadMediaItem(ctx, fileInfo, telegramConfig.token).catch(e => {
158
- console.error('Media download error:', e.message);
159
- return null;
160
- });
161
- if (!item) return;
162
-
163
- const userDir = ensureUserDir(userId);
164
- const tz = getUserTimezone(deps.config, userId);
165
- const today = new Date().toLocaleDateString('en-CA', { timeZone: tz });
166
- const assetsDir = path.join(userDir, 'assets', today);
167
- item.savedPath = media.saveFile(item.buffer, assetsDir, item.filename);
168
-
169
180
  const groupId = ctx.message.media_group_id;
170
181
  if (groupId) {
171
182
  const existing = mediaGroups.get(groupId);
172
183
  if (existing) {
173
184
  clearTimeout(existing.timer);
174
- existing.items.push(item);
175
- existing.ctx = ctx;
185
+ existing.entries.push({ ctx, fileInfo });
186
+ existing.latestCtx = ctx;
176
187
  existing.timer = setTimeout(() => {
177
188
  mediaGroups.delete(groupId);
178
- processMediaItems(existing.ctx, existing.items, deps).catch(e =>
189
+ downloadAndProcess(existing.latestCtx, existing.entries, deps, telegramConfig.token).catch(e =>
179
190
  console.error('Media group error:', e.message)
180
191
  );
181
192
  }, MEDIA_GROUP_DELAY_MS);
182
193
  } else {
183
194
  const group = {
184
- items: [item],
185
- ctx,
195
+ entries: [{ ctx, fileInfo }],
196
+ latestCtx: ctx,
186
197
  timer: setTimeout(() => {
187
198
  mediaGroups.delete(groupId);
188
- processMediaItems(ctx, [item], deps).catch(e =>
199
+ downloadAndProcess(ctx, [{ ctx, fileInfo }], deps, telegramConfig.token).catch(e =>
189
200
  console.error('Media group error:', e.message)
190
201
  );
191
202
  }, MEDIA_GROUP_DELAY_MS),
@@ -195,6 +206,18 @@ function registerMediaHandler(bot, telegramConfig, deps) {
195
206
  return;
196
207
  }
197
208
 
209
+ const item = await downloadMediaItem(ctx, fileInfo, telegramConfig.token).catch(e => {
210
+ console.error('Media download error:', e.message);
211
+ return null;
212
+ });
213
+ if (!item) return;
214
+
215
+ const userDir = ensureUserDir(userId);
216
+ const tz = getUserTimezone(deps.config, userId);
217
+ const today = new Date().toLocaleDateString('en-CA', { timeZone: tz });
218
+ const assetsDir = path.join(userDir, 'assets', today);
219
+ item.savedPath = media.saveFile(item.buffer, assetsDir, item.filename);
220
+
198
221
  await processMediaItems(ctx, [item], deps);
199
222
  }
200
223