agentgui 1.0.90 → 1.0.92

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/.prd CHANGED
@@ -1,40 +0,0 @@
1
- # AgentGUI HTML Rendering Implementation - IN PROGRESS
2
-
3
- ## Task
4
- Implement markdown code block parsing within text blocks to enable HTML rendering in conversation messages.
5
-
6
- ## Work Items
7
-
8
- ### 1. Implement parseMarkdownCodeBlocks() in client.js
9
- - Parse ```language\ncode``` patterns from text blocks
10
- - Use regex: /```(\w*)\n([\s\S]*?)```/g
11
- - Return array of parts with type ('text' or 'code') and content/language/code
12
- - Handle text before, after, and between code blocks
13
-
14
- ### 2. Update renderMessageContent() in client.js
15
- - For text blocks, check if they contain markdown code blocks
16
- - If markdown blocks found, parse and render each part
17
- - For code blocks with language='html', render with innerHTML
18
- - For other code blocks, render as escaped text with monospace font
19
- - Apply "Rendered HTML" badge styling for HTML blocks
20
-
21
- ### 3. Add CSS styling for rendered HTML blocks
22
- - .html-rendered-label: blue background, white text, small font, padding
23
- - .html-content: white background, border, padding, overflow handling
24
- - Support both light and dark modes with CSS variables
25
-
26
- ### 4. Test HTML rendering
27
- - Open "HTML Test" conversation in agent-browser
28
- - Verify HTML table renders as actual table element
29
- - Verify "Rendered HTML" badge appears
30
- - Verify no escaped HTML entities visible
31
- - Verify no markdown delimiters visible
32
- - Verify CSS styling applies correctly
33
-
34
- ## Files to Modify
35
- - /config/workspace/agentgui/static/js/client.js
36
- - Add parseMarkdownCodeBlocks() method
37
- - Update renderMessageContent() to use parser for text blocks
38
-
39
- ## Status
40
- PENDING: Implementation not yet complete
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.90",
3
+ "version": "1.0.92",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/static/index.html CHANGED
@@ -661,6 +661,78 @@
661
661
  }
662
662
  }
663
663
 
664
+ /* HTML rendered content blocks */
665
+ .html-rendered-label {
666
+ padding: 0.5rem;
667
+ background: #eff6ff;
668
+ border: 1px solid #bfdbfe;
669
+ border-radius: 0.25rem;
670
+ font-size: 0.75rem;
671
+ font-weight: 600;
672
+ color: #1d4ed8;
673
+ text-transform: uppercase;
674
+ letter-spacing: 0.05em;
675
+ margin-bottom: 0.5rem;
676
+ }
677
+
678
+ html.dark .html-rendered-label {
679
+ background: #1e3a5f;
680
+ border-color: #2563eb;
681
+ color: #93c5fd;
682
+ }
683
+
684
+ .html-content {
685
+ background: #ffffff;
686
+ padding: 1rem;
687
+ border-radius: 0.375rem;
688
+ border: 1px solid var(--color-border);
689
+ overflow-x: auto;
690
+ }
691
+
692
+ html.dark .html-content {
693
+ background: #1f2937;
694
+ }
695
+
696
+ .html-content table {
697
+ border-collapse: collapse;
698
+ width: 100%;
699
+ margin: 0.5rem 0;
700
+ }
701
+
702
+ .html-content th,
703
+ .html-content td {
704
+ border: 1px solid var(--color-border);
705
+ padding: 0.5rem 0.75rem;
706
+ text-align: left;
707
+ font-size: 0.875rem;
708
+ }
709
+
710
+ .html-content th {
711
+ background: var(--color-bg-secondary);
712
+ font-weight: 600;
713
+ }
714
+
715
+ .html-content ul,
716
+ .html-content ol {
717
+ padding-left: 1.5rem;
718
+ margin: 0.5rem 0;
719
+ }
720
+
721
+ .html-content li {
722
+ margin: 0.25rem 0;
723
+ }
724
+
725
+ .html-content h1,
726
+ .html-content h2,
727
+ .html-content h3,
728
+ .html-content h4 {
729
+ margin: 0.75rem 0 0.5rem;
730
+ }
731
+
732
+ .html-content p {
733
+ margin: 0.5rem 0;
734
+ }
735
+
664
736
  /* Syntax highlighting adjustments */
665
737
  pre {
666
738
  margin: 0;
@@ -726,7 +726,14 @@ class AgentGUIClient {
726
726
  if (msg.content.blocks && Array.isArray(msg.content.blocks)) {
727
727
  msg.content.blocks.forEach(block => {
728
728
  if (block.type === 'text') {
729
- contentHtml += `<div class="message-text">${this.escapeHtml(block.text)}</div>`;
729
+ const parts = this.parseMarkdownCodeBlocks(block.text);
730
+ parts.forEach(part => {
731
+ if (part.type === 'text') {
732
+ contentHtml += `<div class="message-text">${this.escapeHtml(part.content)}</div>`;
733
+ } else if (part.type === 'code') {
734
+ contentHtml += this.renderCodeBlock(part.language, part.code);
735
+ }
736
+ });
730
737
  } else if (block.type === 'code_block') {
731
738
  // Render HTML code blocks as actual HTML elements
732
739
  if (block.language === 'html') {
@@ -569,6 +569,34 @@ class StreamingRenderer {
569
569
  return div;
570
570
  }
571
571
 
572
+ /**
573
+ * Parse markdown code blocks from text
574
+ */
575
+ parseMarkdownCodeBlocks(text) {
576
+ const codeBlockRegex = /```(\w*)\n([\s\S]*?)```/g;
577
+ const parts = [];
578
+ let lastIndex = 0;
579
+ let match;
580
+
581
+ while ((match = codeBlockRegex.exec(text)) !== null) {
582
+ if (match.index > lastIndex) {
583
+ parts.push({ type: 'text', content: text.substring(lastIndex, match.index) });
584
+ }
585
+ parts.push({ type: 'code', language: match[1] || 'plain', code: match[2] });
586
+ lastIndex = codeBlockRegex.lastIndex;
587
+ }
588
+
589
+ if (lastIndex < text.length) {
590
+ parts.push({ type: 'text', content: text.substring(lastIndex) });
591
+ }
592
+
593
+ if (parts.length === 0) {
594
+ return [{ type: 'text', content: text }];
595
+ }
596
+
597
+ return parts;
598
+ }
599
+
572
600
  /**
573
601
  * Render text block event
574
602
  */
@@ -579,7 +607,21 @@ class StreamingRenderer {
579
607
  div.dataset.eventType = 'text_block';
580
608
 
581
609
  const text = event.text || event.content || '';
582
- div.innerHTML = `<p class="text-sm leading-relaxed">${this.escapeHtml(text)}</p>`;
610
+ const parts = this.parseMarkdownCodeBlocks(text);
611
+ let html = '';
612
+ parts.forEach(part => {
613
+ if (part.type === 'text') {
614
+ html += `<p class="text-sm leading-relaxed">${this.escapeHtml(part.content)}</p>`;
615
+ } else if (part.type === 'code') {
616
+ if (part.language.toLowerCase() === 'html') {
617
+ html += `<div class="html-rendered-label mb-2 p-2 bg-blue-50 rounded border text-xs" style="color:#1d4ed8;background:#eff6ff;border-color:#bfdbfe;">Rendered HTML</div>`;
618
+ html += `<div class="html-content bg-white p-4 rounded border overflow-x-auto" style="background:#fff;border-color:#e5e7eb;">${part.code}</div>`;
619
+ } else {
620
+ html += `<pre class="bg-gray-900 text-gray-100 p-4 rounded overflow-x-auto"><code>${this.escapeHtml(part.code)}</code></pre>`;
621
+ }
622
+ }
623
+ });
624
+ div.innerHTML = html;
583
625
  return div;
584
626
  }
585
627