@clawchatsai/connector 0.0.45 → 0.0.47

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +4 -67
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawchatsai/connector",
3
- "version": "0.0.45",
3
+ "version": "0.0.47",
4
4
  "type": "module",
5
5
  "description": "ClawChats OpenClaw plugin — P2P tunnel + local API bridge",
6
6
  "main": "dist/index.js",
package/server.js CHANGED
@@ -3969,7 +3969,6 @@ export function createApp(config = {}) {
3969
3969
  this._externalBroadcastTargets = [];
3970
3970
  this.streamState = new Map();
3971
3971
  this.activityLogs = new Map();
3972
- this._pendingMediaUrls = new Map(); // sessionKey → string[] of MEDIA: paths captured during streaming
3973
3972
  setInterval(() => {
3974
3973
  const cutoff = Date.now() - 10 * 60 * 1000;
3975
3974
  for (const [runId, log] of this.activityLogs) {
@@ -4066,42 +4065,6 @@ export function createApp(config = {}) {
4066
4065
  if (!content || !content.trim()) { console.log(`Skipping empty assistant response for thread ${parsed.threadId}`); return; }
4067
4066
  const now = Date.now();
4068
4067
 
4069
- // Check if the final assembled message content contains MEDIA: lines
4070
- console.log('[ClawChats] saveAssistantMessage hasMedia:', content.includes('MEDIA:'), 'msgKeys:', Object.keys(message||{}), 'msgMediaUrls:', JSON.stringify(message?.mediaUrls), 'msgMediaUrl:', message?.mediaUrl);
4071
-
4072
- // Extract MEDIA: paths from the final complete message content (if gateway preserves them here)
4073
- let attachments = null;
4074
- const mediaMatches = [...content.matchAll(/^MEDIA:\s*(\S+)/gm)].map(m => m[1].trim()).filter(p => /\.\w{1,10}$/.test(p));
4075
- if (mediaMatches.length > 0) {
4076
- console.log('[ClawChats] MEDIA paths from final content:', JSON.stringify(mediaMatches));
4077
- attachments = mediaMatches.map(filePath => {
4078
- const name = path.basename(filePath);
4079
- const ext = (name.split('.').pop() || '').toLowerCase();
4080
- const type = ['jpg','jpeg','png','gif','webp','svg','bmp','ico'].includes(ext) ? 'image'
4081
- : ['mp3','wav','ogg','aac','m4a','flac','opus'].includes(ext) ? 'audio'
4082
- : ['mp4','webm','mov','avi','mkv'].includes(ext) ? 'video' : 'file';
4083
- return { path: filePath, name, type };
4084
- });
4085
- }
4086
-
4087
- // Fallback: use MEDIA: paths captured from delta stream
4088
- if (!attachments) {
4089
- const paths = this._pendingMediaUrls.get(sessionKey);
4090
- this._pendingMediaUrls.delete(sessionKey);
4091
- if (paths?.length) {
4092
- attachments = paths.map(filePath => {
4093
- const name = path.basename(filePath);
4094
- const ext = (name.split('.').pop() || '').toLowerCase();
4095
- const type = ['jpg','jpeg','png','gif','webp','svg','bmp','ico'].includes(ext) ? 'image'
4096
- : ['mp3','wav','ogg','aac','m4a','flac','opus'].includes(ext) ? 'audio'
4097
- : ['mp4','webm','mov','avi','mkv'].includes(ext) ? 'video' : 'file';
4098
- return { path: filePath, name, type };
4099
- });
4100
- }
4101
- } else {
4102
- this._pendingMediaUrls.delete(sessionKey); // clean up either way
4103
- }
4104
-
4105
4068
  // Check for pending activity message
4106
4069
  const pendingMsg = db.prepare(`
4107
4070
  SELECT id, metadata FROM messages
@@ -4121,15 +4084,13 @@ export function createApp(config = {}) {
4121
4084
  if (lastAssistantIdx >= 0) metadata.activityLog.splice(lastAssistantIdx, 1);
4122
4085
  metadata.activitySummary = this.generateActivitySummary(metadata.activityLog);
4123
4086
  }
4124
- if (attachments) metadata.attachments = attachments;
4125
4087
  db.prepare('UPDATE messages SET content = ?, metadata = ?, timestamp = ? WHERE id = ?')
4126
4088
  .run(content, JSON.stringify(metadata), now, pendingMsg.id);
4127
4089
  messageId = pendingMsg.id;
4128
4090
  } else {
4129
4091
  // No pending activity — normal INSERT (simple responses, no tools)
4130
4092
  messageId = seq != null ? `gw-${parsed.threadId}-${seq}` : `gw-${parsed.threadId}-${now}`;
4131
- const metaStr = attachments ? JSON.stringify({ attachments }) : null;
4132
- db.prepare(`INSERT INTO messages (id, thread_id, role, content, status, metadata, timestamp, created_at) VALUES (?, ?, 'assistant', ?, 'sent', ?, ?, ?) ON CONFLICT(id) DO UPDATE SET content = excluded.content, metadata = COALESCE(excluded.metadata, metadata), timestamp = excluded.timestamp`).run(messageId, parsed.threadId, content, metaStr, now, now);
4093
+ db.prepare(`INSERT INTO messages (id, thread_id, role, content, status, timestamp, created_at) VALUES (?, ?, 'assistant', ?, 'sent', ?, ?) ON CONFLICT(id) DO UPDATE SET content = excluded.content, timestamp = excluded.timestamp`).run(messageId, parsed.threadId, content, now, now);
4133
4094
  }
4134
4095
 
4135
4096
  try {
@@ -4171,8 +4132,6 @@ export function createApp(config = {}) {
4171
4132
  } catch (e) { console.error(`Failed to save error marker:`, e.message); }
4172
4133
  }
4173
4134
 
4174
- // _scanRecentWorkspaceFiles removed — MEDIA: paths captured from delta stream instead
4175
-
4176
4135
  generateThreadTitle(db, threadId, workspace, skipHeuristic = false) {
4177
4136
  const thread = db.prepare('SELECT title FROM threads WHERE id = ?').get(threadId);
4178
4137
  if (!thread) return;
@@ -4223,25 +4182,7 @@ export function createApp(config = {}) {
4223
4182
  if (!this.activityLogs.has(runId)) this.activityLogs.set(runId, { sessionKey, steps: [], startTime: Date.now() });
4224
4183
  const log = this.activityLogs.get(runId);
4225
4184
  if (stream === 'assistant') {
4226
- // Check data.mediaUrls — gateway populates this via splitMediaFromOutput on each streaming event.
4227
- // Partial path events (e.g. ["/"]) fail the extension filter; complete-path events pass.
4228
- const incomingUrls = Array.isArray(data?.mediaUrls) ? data.mediaUrls : (data?.mediaUrl ? [data.mediaUrl] : []);
4229
- for (const p of incomingUrls) {
4230
- if (typeof p === 'string' && /\.\w{1,10}$/.test(p)) {
4231
- if (!log._seenMediaPaths) log._seenMediaPaths = new Set();
4232
- if (!log._seenMediaPaths.has(p)) {
4233
- log._seenMediaPaths.add(p);
4234
- if (!this._pendingMediaUrls.has(sessionKey)) this._pendingMediaUrls.set(sessionKey, []);
4235
- this._pendingMediaUrls.get(sessionKey).push(p);
4236
- console.log('[ClawChats] MEDIA path captured from mediaUrls:', p);
4237
- }
4238
- }
4239
- }
4240
- if (incomingUrls.length > 0) console.log('[ClawChats] mediaUrls on event:', JSON.stringify(incomingUrls));
4241
4185
  const text = data?.text || '';
4242
- const delta = data?.delta || '';
4243
- // Log if a MEDIA: directive appears in text or delta (must look like an actual path, not just the word)
4244
- if (/MEDIA:\s*[./~a-zA-Z]/.test(text.slice(-80)) || /MEDIA:\s*[./~a-zA-Z]/.test(delta)) console.log('[ClawChats] MEDIA in stream! text tail:', JSON.stringify(text.slice(-80)), 'delta:', JSON.stringify(delta));
4245
4186
  if (text) {
4246
4187
  let currentSegment = log._currentAssistantSegment;
4247
4188
  if (!currentSegment || currentSegment._sealed) {
@@ -4268,7 +4209,6 @@ export function createApp(config = {}) {
4268
4209
  if (log._currentAssistantSegment && !log._currentAssistantSegment._sealed) { log._currentAssistantSegment._sealed = true; }
4269
4210
  const step = { type: 'tool', timestamp: Date.now(), name: data?.name || 'unknown', phase: data?.phase || 'start', toolCallId: data?.toolCallId, meta: data?.meta, isError: data?.isError || false };
4270
4211
  if (data?.phase === 'result') {
4271
- if (data?.name === 'exec') console.log('[ClawChats] exec tool result meta:', JSON.stringify(data?.meta));
4272
4212
  const existing = log.steps.findLast(s => s.toolCallId === data.toolCallId && (s.phase === 'start' || s.phase === 'running'));
4273
4213
  if (existing) { existing.phase = 'done'; existing.resultMeta = data?.meta; existing.isError = data?.isError || false; existing.durationMs = Date.now() - existing.timestamp; }
4274
4214
  else { step.phase = 'done'; log.steps.push(step); }
@@ -4281,7 +4221,6 @@ export function createApp(config = {}) {
4281
4221
  }
4282
4222
  if (stream === 'lifecycle') {
4283
4223
  if (data?.phase === 'end' || data?.phase === 'error') {
4284
- // MEDIA: paths already captured during delta streaming — nothing to do here
4285
4224
  if (log._currentAssistantSegment && !log._currentAssistantSegment._sealed) log._currentAssistantSegment._sealed = true;
4286
4225
  const lastAssistantIdx = log.steps.findLastIndex(s => s.type === 'assistant');
4287
4226
  if (lastAssistantIdx >= 0) log.steps.splice(lastAssistantIdx, 1);
@@ -4608,7 +4547,7 @@ export function createApp(config = {}) {
4608
4547
  }
4609
4548
 
4610
4549
  // ── Browser WebSocket setup (shared logic for standalone and plugin) ────────
4611
- function _setupBrowserWs(wssInstance) {
4550
+ function _setupBrowserWs(wssInstance) {
4612
4551
  wssInstance.on('connection', (ws) => {
4613
4552
  console.log('Browser client connected');
4614
4553
  _gatewayClient.addBrowserClient(ws);
@@ -4618,7 +4557,6 @@ export function createApp(config = {}) {
4618
4557
  ws.on('message', (data) => {
4619
4558
  const msgStr = data.toString();
4620
4559
  _debugLogger.logFrame('BR→SRV', msgStr);
4621
- let forwardStr = msgStr;
4622
4560
  try {
4623
4561
  const msg = JSON.parse(msgStr);
4624
4562
  if (msg.type === 'req' && msg.method === 'connect') {
@@ -4638,9 +4576,8 @@ export function createApp(config = {}) {
4638
4576
  if (msg.action === 'debug-start') { const result = _debugLogger.start(msg.ts, ws); if (result.error === 'already-active') ws.send(JSON.stringify({ type: 'clawchats', event: 'debug-error', error: 'Recording already active in another tab', sessionId: result.sessionId })); else ws.send(JSON.stringify({ type: 'clawchats', event: 'debug-started', sessionId: result.sessionId })); return; }
4639
4577
  if (msg.action === 'debug-dump') { const { sessionId, files } = _debugLogger.saveDump(msg); ws.send(JSON.stringify({ type: 'clawchats', event: 'debug-saved', sessionId, files })); return; }
4640
4578
  }
4641
- // (no hint injection mediaUrls are captured from agent events directly)
4642
- } catch { /* Not JSON or not a ClawChats message, forward as-is */ }
4643
- _gatewayClient.sendToGateway(forwardStr);
4579
+ } catch { /* Not JSON or not a ClawChats message, forward to gateway */ }
4580
+ _gatewayClient.sendToGateway(msgStr);
4644
4581
  });
4645
4582
 
4646
4583
  ws.on('close', () => { console.log('Browser client disconnected'); _debugLogger.handleClientDisconnect(ws); _gatewayClient.removeBrowserClient(ws); });