sam-coder-cli 1.0.15 → 1.0.16

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.
@@ -235,59 +235,61 @@ class MultiplayerClient extends EventEmitter {
235
235
  this.clients = [];
236
236
  this.currentTask = null;
237
237
  this.taskQueue = [];
238
+ this.pendingTasks = new Map();
239
+ this.taskResults = new Map();
238
240
  this.rl = options.rl || readline.createInterface({
239
241
  input: process.stdin,
240
242
  output: process.stdout
241
243
  });
244
+
245
+ // Bind methods
246
+ this.processTaskQueue = this.processTaskQueue.bind(this);
247
+ this.completeTask = this.completeTask.bind(this);
242
248
  }
243
249
 
244
250
  async connect() {
245
251
  try {
246
- // Ensure server is running and get the correct URL
247
- const url = new URL(this.serverUrl);
248
- const serverPort = url.port || 8080;
249
- this.serverUrl = await ensureServerRunning(serverPort);
252
+ // Ensure server is running
253
+ this.serverUrl = await ensureServerRunning(this.port);
250
254
 
251
- return new Promise((resolve, reject) => {
252
- this.ws = new WebSocket(this.serverUrl);
253
-
254
- this.ws.on('open', () => {
255
- this.connected = true;
256
- // Send client info immediately after connection
257
- this.send({
258
- type: 'client_info',
259
- clientInfo: {
260
- name: this.name || `Agent-${Math.random().toString(36).substr(2, 4)}`,
261
- role: this.role || 'Assistant',
262
- model: this.model || 'default'
263
- }
264
- });
265
- this.emit('connected');
266
- resolve();
267
- });
268
-
269
- this.ws.on('message', (data) => {
270
- try {
271
- const message = JSON.parse(data);
272
- this.handleMessage(message);
273
- } catch (error) {
274
- console.error('Error parsing message:', error);
275
- }
276
- });
277
-
278
- this.ws.on('close', () => {
279
- this.connected = false;
280
- this.emit('disconnected');
281
- });
255
+ this.ws = new WebSocket(this.serverUrl);
256
+
257
+ this.ws.on('open', () => {
258
+ this.connected = true;
259
+ this.emit('connected');
260
+ console.log(chalk.green('āœ… Connected to multiplayer server'));
282
261
 
283
- this.ws.on('error', (error) => {
284
- this.connected = false;
285
- reject(error);
262
+ // Send client info immediately after connection
263
+ this.updateClientInfo({
264
+ name: this.name,
265
+ role: this.role,
266
+ model: this.model
286
267
  });
287
268
  });
269
+
270
+ this.ws.on('message', (data) => {
271
+ try {
272
+ const message = JSON.parse(data);
273
+ this.handleMessage(message);
274
+ } catch (error) {
275
+ console.error('Error parsing message:', error);
276
+ }
277
+ });
278
+
279
+ this.ws.on('close', () => {
280
+ this.connected = false;
281
+ this.emit('disconnected');
282
+ console.log(chalk.yellow('\nšŸ”Œ Disconnected from multiplayer server'));
283
+ });
284
+
285
+ this.ws.on('error', (error) => {
286
+ console.error('WebSocket error:', error);
287
+ this.emit('error', error);
288
+ });
289
+
288
290
  } catch (error) {
289
- console.error('Failed to start multiplayer server:', error);
290
- throw error;
291
+ console.error('Failed to connect to server:', error);
292
+ this.emit('error', error);
291
293
  }
292
294
  }
293
295
 
@@ -398,13 +400,22 @@ class MultiplayerClient extends EventEmitter {
398
400
  this.emit('work_updated', message);
399
401
  }
400
402
 
401
- handleTaskAssigned(task) {
402
- console.log(`\n New task assigned: ${task.prompt}`);
403
- console.log(`Type: ${task.taskType} | Assigned by: ${this.getClientName(task.assignedBy)}\n`);
403
+ async handleTaskAssigned(task) {
404
+ console.log(chalk.magenta(`\nšŸ“‹ New Task: ${task.prompt}`));
405
+ console.log(chalk.dim(`Type: ${task.taskType} | Assigned by: ${this.getClientName(task.assignedBy)}\n`));
404
406
 
405
- // Add to task queue
406
- this.taskQueue.push(task);
407
- this.processTaskQueue();
407
+ // Store task in pending tasks
408
+ this.pendingTasks.set(task.id, {
409
+ ...task,
410
+ status: 'pending',
411
+ assignedAt: new Date().toISOString()
412
+ });
413
+
414
+ // Add to task queue if it's assigned to this client or to all
415
+ if (!task.assignedTo || task.assignedTo === this.clientId) {
416
+ this.taskQueue.push(task);
417
+ this.processTaskQueue();
418
+ }
408
419
 
409
420
  this.emit('task_assigned', task);
410
421
  }
@@ -413,34 +424,57 @@ class MultiplayerClient extends EventEmitter {
413
424
  if (this.currentTask || this.taskQueue.length === 0) return;
414
425
 
415
426
  this.currentTask = this.taskQueue.shift();
427
+ const taskId = this.currentTask.id;
416
428
 
417
429
  try {
418
- // Simulate working on the task
419
- console.log(`\n Working on task: ${this.currentTask.prompt}`);
420
-
421
- // Here you would integrate with your AI to process the task
422
- // For now, we'll just simulate work
423
- await new Promise(resolve => setTimeout(resolve, 2000));
424
-
425
- const result = {
426
- taskId: this.currentTask.id,
427
- result: `Completed task: ${this.currentTask.prompt}`,
428
- timestamp: new Date().toISOString()
429
- };
430
+ // Update task status to in-progress
431
+ this.pendingTasks.set(taskId, {
432
+ ...this.pendingTasks.get(taskId),
433
+ status: 'in_progress',
434
+ startedAt: new Date().toISOString()
435
+ });
430
436
 
431
- // Send result back to server
437
+ // Notify others about task progress
432
438
  this.send({
433
- type: 'task_result',
439
+ type: 'task_progress',
434
440
  sessionId: this.sessionId,
435
- taskId: this.currentTask.id,
436
- result: result.result,
437
- timestamp: result.timestamp
441
+ taskId,
442
+ status: 'in_progress',
443
+ progress: 0,
444
+ timestamp: new Date().toISOString()
438
445
  });
439
446
 
440
- console.log(` Completed task: ${this.currentTask.prompt}`);
447
+ console.log(chalk.blue(`\nšŸ”„ [${this.role}] Working on: ${this.currentTask.prompt}`));
448
+
449
+ // Simulate work with progress updates
450
+ const totalSteps = 5;
451
+ for (let i = 0; i < totalSteps; i++) {
452
+ await new Promise(resolve => setTimeout(resolve, 500));
453
+ const progress = Math.floor(((i + 1) / totalSteps) * 100);
454
+
455
+ // Update progress
456
+ this.send({
457
+ type: 'task_progress',
458
+ sessionId: this.sessionId,
459
+ taskId,
460
+ status: 'in_progress',
461
+ progress,
462
+ timestamp: new Date().toISOString()
463
+ });
464
+ }
465
+
466
+ // Complete the task
467
+ await this.completeTask(taskId);
441
468
 
442
469
  } catch (error) {
443
470
  console.error('Error processing task:', error);
471
+ this.send({
472
+ type: 'task_failed',
473
+ sessionId: this.sessionId,
474
+ taskId,
475
+ error: error.message,
476
+ timestamp: new Date().toISOString()
477
+ });
444
478
  } finally {
445
479
  this.currentTask = null;
446
480
  // Process next task if available
@@ -449,6 +483,52 @@ class MultiplayerClient extends EventEmitter {
449
483
  }
450
484
  }
451
485
  }
486
+
487
+ async completeTask(taskId) {
488
+ const task = this.pendingTasks.get(taskId);
489
+ if (!task) return null;
490
+
491
+ // Generate task result based on task type
492
+ let result;
493
+ switch (task.taskType) {
494
+ case 'research':
495
+ result = `Research completed on: ${task.prompt}\nSummary: This is a simulated research result.`;
496
+ break;
497
+ case 'code':
498
+ result = `Code implementation for: ${task.prompt}\n// Simulated code implementation\nfunction ${task.prompt.split(' ')[0].toLowerCase()}() {\n // TODO: Implement\n}`;
499
+ break;
500
+ case 'debug':
501
+ result = `Debugging analysis for: ${task.prompt}\n- Issue identified: Simulated issue\n- Solution: Simulated fix`;
502
+ break;
503
+ default:
504
+ result = `Completed: ${task.prompt}`;
505
+ }
506
+
507
+ // Update task status
508
+ const completedTask = {
509
+ ...task,
510
+ status: 'completed',
511
+ completedAt: new Date().toISOString(),
512
+ result
513
+ };
514
+
515
+ this.pendingTasks.set(taskId, completedTask);
516
+ this.taskResults.set(taskId, result);
517
+
518
+ // Notify server and other clients
519
+ this.send({
520
+ type: 'task_completed',
521
+ sessionId: this.sessionId,
522
+ taskId,
523
+ result,
524
+ timestamp: new Date().toISOString()
525
+ });
526
+
527
+ console.log(chalk.green(`\nāœ… [${this.role}] Completed: ${task.prompt}`));
528
+ this.emit('task_completed', completedTask);
529
+
530
+ return completedTask;
531
+ }
452
532
 
453
533
  handleTaskCompleted(data) {
454
534
  console.log(`\n Task completed by all agents!`);
@@ -462,19 +542,52 @@ class MultiplayerClient extends EventEmitter {
462
542
  this.emit('task_completed', data);
463
543
  }
464
544
 
465
- updateWork(work) {
545
+ async updateWork(work) {
466
546
  const workItem = {
547
+ id: uuidv4(),
467
548
  ...work,
468
549
  clientId: this.clientId,
469
- status: work.status || 'in_progress',
470
- timestamp: new Date().toISOString()
550
+ clientName: this.name,
551
+ timestamp: new Date().toISOString(),
552
+ status: work.status || 'in_progress'
471
553
  };
472
-
554
+
555
+ this.workHistory.push(workItem);
556
+
557
+ // Keep only the last 10 work items
558
+ if (this.workHistory.length > 10) {
559
+ this.workHistory = this.workHistory.slice(-10);
560
+ }
561
+
473
562
  this.send({
474
563
  type: 'work_update',
475
564
  sessionId: this.sessionId,
476
- work: workUpdate
565
+ ...workItem
477
566
  });
567
+
568
+ this.emit('work_updated', workItem);
569
+ return workItem;
570
+ }
571
+
572
+ async updateClientInfo(updates) {
573
+ // Update local client info
574
+ Object.assign(this, updates);
575
+
576
+ // Notify server about the update
577
+ if (this.connected) {
578
+ this.send({
579
+ type: 'client_update',
580
+ sessionId: this.sessionId,
581
+ clientId: this.clientId,
582
+ updates: {
583
+ name: this.name,
584
+ role: this.role,
585
+ model: this.model,
586
+ updatedAt: new Date().toISOString()
587
+ },
588
+ timestamp: new Date().toISOString()
589
+ });
590
+ }
478
591
  }
479
592
 
480
593
  assignTask(task, assigneeClientId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sam-coder-cli",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "SAM-CODER: An animated command-line AI assistant with agency capabilities.",
5
5
  "main": "bin/agi-cli.js",
6
6
  "bin": {