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