agentgui 1.0.98 → 1.0.100

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": "agentgui",
3
- "version": "1.0.98",
3
+ "version": "1.0.100",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
@@ -377,10 +377,21 @@ class AgentGUIClient {
377
377
  renderBlockContent(block) {
378
378
  if (block.type === 'text' && block.text) {
379
379
  const text = block.text;
380
- if (text.includes('<') && (text.includes('</') || text.includes('/>'))) {
381
- return text;
380
+ if (this.isHtmlContent(text)) {
381
+ return `<div class="html-content bg-white dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">${text}</div>`;
382
382
  }
383
- return this.escapeHtml(text);
383
+ const parts = this.parseMarkdownCodeBlocks(text);
384
+ if (parts.length === 1 && parts[0].type === 'text') {
385
+ return this.escapeHtml(text);
386
+ }
387
+ return parts.map(part => {
388
+ if (part.type === 'html') {
389
+ return `<div class="html-content bg-white dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">${part.content}</div>`;
390
+ } else if (part.type === 'code') {
391
+ return this.renderCodeBlock(part.language, part.code);
392
+ }
393
+ return this.escapeHtml(part.content);
394
+ }).join('');
384
395
  }
385
396
  return this.escapeHtml(JSON.stringify(block));
386
397
  }
@@ -493,10 +504,12 @@ class AgentGUIClient {
493
504
  }
494
505
  }
495
506
 
496
- /**
497
- * Parse markdown code blocks from text
498
- * Returns array of parts with type ('text' or 'code') and content/language/code
499
- */
507
+ isHtmlContent(text) {
508
+ const openTag = /<(?:div|table|section|article|form|ul|ol|dl|nav|header|footer|main|aside|figure|details|summary|h[1-6])\b[^>]*>/i;
509
+ const closeTag = /<\/(?:div|table|section|article|form|ul|ol|dl|nav|header|footer|main|aside|figure|details|summary|h[1-6])>/i;
510
+ return openTag.test(text) && closeTag.test(text);
511
+ }
512
+
500
513
  parseMarkdownCodeBlocks(text) {
501
514
  const codeBlockRegex = /```(\w*)\n([\s\S]*?)```/g;
502
515
  const parts = [];
@@ -504,14 +517,13 @@ class AgentGUIClient {
504
517
  let match;
505
518
 
506
519
  while ((match = codeBlockRegex.exec(text)) !== null) {
507
- // Add text before the code block
508
520
  if (match.index > lastIndex) {
521
+ const segment = text.substring(lastIndex, match.index);
509
522
  parts.push({
510
- type: 'text',
511
- content: text.substring(lastIndex, match.index)
523
+ type: this.isHtmlContent(segment) ? 'html' : 'text',
524
+ content: segment
512
525
  });
513
526
  }
514
- // Add the code block
515
527
  parts.push({
516
528
  type: 'code',
517
529
  language: match[1] || 'plain',
@@ -520,17 +532,16 @@ class AgentGUIClient {
520
532
  lastIndex = codeBlockRegex.lastIndex;
521
533
  }
522
534
 
523
- // Add remaining text after last code block
524
535
  if (lastIndex < text.length) {
536
+ const segment = text.substring(lastIndex);
525
537
  parts.push({
526
- type: 'text',
527
- content: text.substring(lastIndex)
538
+ type: this.isHtmlContent(segment) ? 'html' : 'text',
539
+ content: segment
528
540
  });
529
541
  }
530
542
 
531
- // If no code blocks found, return the text as-is
532
543
  if (parts.length === 0) {
533
- return [{ type: 'text', content: text }];
544
+ return [{ type: this.isHtmlContent(text) ? 'html' : 'text', content: text }];
534
545
  }
535
546
 
536
547
  return parts;
@@ -561,16 +572,20 @@ class AgentGUIClient {
561
572
  */
562
573
  renderMessageContent(content) {
563
574
  if (typeof content === 'string') {
575
+ if (this.isHtmlContent(content)) {
576
+ return `<div class="message-text"><div class="html-content bg-white dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">${content}</div></div>`;
577
+ }
564
578
  return `<div class="message-text">${this.escapeHtml(content)}</div>`;
565
579
  } else if (content && typeof content === 'object' && content.type === 'claude_execution') {
566
580
  let html = '<div class="message-blocks">';
567
581
  if (content.blocks && Array.isArray(content.blocks)) {
568
582
  content.blocks.forEach(block => {
569
583
  if (block.type === 'text') {
570
- // Parse markdown code blocks from text
571
584
  const parts = this.parseMarkdownCodeBlocks(block.text);
572
585
  parts.forEach(part => {
573
- if (part.type === 'text') {
586
+ if (part.type === 'html') {
587
+ html += `<div class="message-text"><div class="html-content bg-white dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">${part.content}</div></div>`;
588
+ } else if (part.type === 'text') {
574
589
  html += `<div class="message-text">${this.escapeHtml(part.content)}</div>`;
575
590
  } else if (part.type === 'code') {
576
591
  html += this.renderCodeBlock(part.language, part.code);
@@ -856,18 +871,22 @@ class AgentGUIClient {
856
871
  return messages.map(msg => {
857
872
  let contentHtml = '';
858
873
 
859
- // Handle different content types
860
874
  if (typeof msg.content === 'string') {
861
- contentHtml = `<div class="message-text">${this.escapeHtml(msg.content)}</div>`;
875
+ if (this.isHtmlContent(msg.content)) {
876
+ contentHtml = `<div class="message-text"><div class="html-content bg-white dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">${msg.content}</div></div>`;
877
+ } else {
878
+ contentHtml = `<div class="message-text">${this.escapeHtml(msg.content)}</div>`;
879
+ }
862
880
  } else if (msg.content && typeof msg.content === 'object' && msg.content.type === 'claude_execution') {
863
- // Handle Claude execution blocks
864
881
  contentHtml = '<div class="message-blocks">';
865
882
  if (msg.content.blocks && Array.isArray(msg.content.blocks)) {
866
883
  msg.content.blocks.forEach(block => {
867
884
  if (block.type === 'text') {
868
885
  const parts = this.parseMarkdownCodeBlocks(block.text);
869
886
  parts.forEach(part => {
870
- if (part.type === 'text') {
887
+ if (part.type === 'html') {
888
+ contentHtml += `<div class="message-text"><div class="html-content bg-white dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">${part.content}</div></div>`;
889
+ } else if (part.type === 'text') {
871
890
  contentHtml += `<div class="message-text">${this.escapeHtml(part.content)}</div>`;
872
891
  } else if (part.type === 'code') {
873
892
  contentHtml += this.renderCodeBlock(part.language, part.code);
@@ -569,9 +569,12 @@ class StreamingRenderer {
569
569
  return div;
570
570
  }
571
571
 
572
- /**
573
- * Parse markdown code blocks from text
574
- */
572
+ isHtmlContent(text) {
573
+ const openTag = /<(?:div|table|section|article|form|ul|ol|dl|nav|header|footer|main|aside|figure|details|summary|h[1-6])\b[^>]*>/i;
574
+ const closeTag = /<\/(?:div|table|section|article|form|ul|ol|dl|nav|header|footer|main|aside|figure|details|summary|h[1-6])>/i;
575
+ return openTag.test(text) && closeTag.test(text);
576
+ }
577
+
575
578
  parseMarkdownCodeBlocks(text) {
576
579
  const codeBlockRegex = /```(\w*)\n([\s\S]*?)```/g;
577
580
  const parts = [];
@@ -580,18 +583,20 @@ class StreamingRenderer {
580
583
 
581
584
  while ((match = codeBlockRegex.exec(text)) !== null) {
582
585
  if (match.index > lastIndex) {
583
- parts.push({ type: 'text', content: text.substring(lastIndex, match.index) });
586
+ const segment = text.substring(lastIndex, match.index);
587
+ parts.push({ type: this.isHtmlContent(segment) ? 'html' : 'text', content: segment });
584
588
  }
585
589
  parts.push({ type: 'code', language: match[1] || 'plain', code: match[2] });
586
590
  lastIndex = codeBlockRegex.lastIndex;
587
591
  }
588
592
 
589
593
  if (lastIndex < text.length) {
590
- parts.push({ type: 'text', content: text.substring(lastIndex) });
594
+ const segment = text.substring(lastIndex);
595
+ parts.push({ type: this.isHtmlContent(segment) ? 'html' : 'text', content: segment });
591
596
  }
592
597
 
593
598
  if (parts.length === 0) {
594
- return [{ type: 'text', content: text }];
599
+ return [{ type: this.isHtmlContent(text) ? 'html' : 'text', content: text }];
595
600
  }
596
601
 
597
602
  return parts;
@@ -610,7 +615,9 @@ class StreamingRenderer {
610
615
  const parts = this.parseMarkdownCodeBlocks(text);
611
616
  let html = '';
612
617
  parts.forEach(part => {
613
- if (part.type === 'text') {
618
+ if (part.type === 'html') {
619
+ html += `<div class="html-content bg-white dark:bg-gray-800 p-4 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">${part.content}</div>`;
620
+ } else if (part.type === 'text') {
614
621
  html += `<p class="text-sm leading-relaxed">${this.escapeHtml(part.content)}</p>`;
615
622
  } else if (part.type === 'code') {
616
623
  if (part.language.toLowerCase() === 'html') {