bloby-bot 0.48.2 → 0.48.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bloby-bot",
3
- "version": "0.48.2",
3
+ "version": "0.48.3",
4
4
  "releaseNotes": [
5
5
  "1. Something great..",
6
6
  "2. ",
@@ -441,7 +441,21 @@ export async function startSupervisor() {
441
441
  const proxy = http.request(
442
442
  { host: '127.0.0.1', port: backendPort, path: backendPath, method: req.method, headers: req.headers },
443
443
  (proxyRes) => {
444
+ const ct = String(proxyRes.headers['content-type'] || '');
445
+ const isSse = ct.includes('text/event-stream');
446
+ if (isSse) {
447
+ console.log(`[app-proxy] SSE upstream status=${proxyRes.statusCode} ct="${ct}" url=${backendPath}`);
448
+ }
444
449
  res.writeHead(proxyRes.statusCode!, proxyRes.headers);
450
+ if (isSse) {
451
+ try { res.socket?.setNoDelay(true); } catch {}
452
+ proxyRes.on('data', (chunk: Buffer) => {
453
+ console.log(`[app-proxy] SSE chunk bytes=${chunk.length} preview=${JSON.stringify(chunk.toString('utf-8').slice(0, 80))}`);
454
+ });
455
+ proxyRes.on('end', () => console.log(`[app-proxy] SSE upstream END`));
456
+ proxyRes.on('error', (e: any) => console.log(`[app-proxy] SSE upstream ERROR ${e.message}`));
457
+ res.on('close', () => console.log(`[app-proxy] SSE res CLOSE`));
458
+ }
445
459
  proxyRes.pipe(res);
446
460
  },
447
461
  );
@@ -1243,25 +1257,33 @@ mint();
1243
1257
  // GET /api/agent/chat/stream — Server-Sent Events, every chat event (bot:*, chat:*)
1244
1258
  if (req.method === 'GET' && agentPath === '/api/agent/chat/stream') {
1245
1259
  const clientId = urlObj.searchParams.get('clientId') || undefined;
1260
+ const subId = crypto.randomBytes(8).toString('hex');
1261
+ console.log(`[sse-handler] OPEN sub=${subId} clientId=${clientId} remote=${req.socket.remoteAddress}`);
1262
+
1246
1263
  res.setHeader('Content-Type', 'text/event-stream');
1247
1264
  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
1248
1265
  res.setHeader('Connection', 'keep-alive');
1249
1266
  res.setHeader('X-Accel-Buffering', 'no');
1250
1267
  res.writeHead(200);
1251
- res.write(': connected\n\n');
1268
+ try { res.socket?.setNoDelay(true); } catch {}
1269
+ const wrote = res.write(': connected\n\n');
1270
+ console.log(`[sse-handler] wrote initial comment sub=${subId} writeOk=${wrote}`);
1252
1271
 
1253
1272
  const sub: ChatSubscriber = {
1254
- id: crypto.randomBytes(8).toString('hex'),
1273
+ id: subId,
1255
1274
  clientId,
1256
1275
  send: (type, data) => {
1257
- if (res.writableEnded) return;
1258
- res.write(`event: ${type}\ndata: ${JSON.stringify(data)}\n\n`);
1276
+ if (res.writableEnded) {
1277
+ console.log(`[sse-handler] skip write (ended) sub=${subId} type=${type}`);
1278
+ return;
1279
+ }
1280
+ const ok = res.write(`event: ${type}\ndata: ${JSON.stringify(data)}\n\n`);
1281
+ console.log(`[sse-handler] write sub=${subId} type=${type} ok=${ok} bytes=${(type.length + JSON.stringify(data).length + 10)}`);
1259
1282
  },
1260
1283
  close: () => { try { res.end(); } catch {} },
1261
1284
  };
1262
1285
  chatSubscribers.add(sub);
1263
1286
 
1264
- // Replay current streaming state so a late-joining workspace catches up mid-turn
1265
1287
  if (agentQueryActive && currentStreamConvId) {
1266
1288
  sub.send('chat:state', {
1267
1289
  streaming: true,
@@ -1273,12 +1295,20 @@ mint();
1273
1295
  const keepAlive = setInterval(() => {
1274
1296
  if (res.writableEnded) return;
1275
1297
  res.write(': ping\n\n');
1298
+ console.log(`[sse-handler] ping sub=${subId}`);
1276
1299
  }, 25_000);
1277
1300
 
1278
1301
  req.on('close', () => {
1302
+ console.log(`[sse-handler] CLOSE sub=${subId} reason=req-close`);
1279
1303
  clearInterval(keepAlive);
1280
1304
  chatSubscribers.delete(sub);
1281
1305
  });
1306
+ res.on('close', () => {
1307
+ console.log(`[sse-handler] CLOSE sub=${subId} reason=res-close`);
1308
+ });
1309
+ res.on('error', (err: any) => {
1310
+ console.log(`[sse-handler] ERROR sub=${subId} ${err?.message}`);
1311
+ });
1282
1312
  return;
1283
1313
  }
1284
1314
 
@@ -1716,11 +1746,18 @@ mint();
1716
1746
  * subscribers. The workspace mirror sees the exact same event stream the widget does. */
1717
1747
  function broadcastBloby(type: string, data: any = {}) {
1718
1748
  const msg = JSON.stringify({ type, data });
1749
+ let wsCount = 0;
1719
1750
  for (const client of blobyWss.clients) {
1720
- if (client.readyState === WebSocket.OPEN) client.send(msg);
1751
+ if (client.readyState === WebSocket.OPEN) { client.send(msg); wsCount++; }
1721
1752
  }
1753
+ let sseCount = 0;
1722
1754
  for (const sub of chatSubscribers) {
1723
- try { sub.send(type, data); } catch {}
1755
+ try { sub.send(type, data); sseCount++; } catch (e: any) {
1756
+ console.log(`[sse-broadcast] send failed sub=${sub.id}: ${e.message}`);
1757
+ }
1758
+ }
1759
+ if (type.startsWith('bot:') || type.startsWith('chat:')) {
1760
+ console.log(`[sse-broadcast] type=${type} ws=${wsCount} sse=${sseCount} subs=${chatSubscribers.size}`);
1724
1761
  }
1725
1762
  }
1726
1763