Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
1472f36
Initial commit. Add Save button with two modes, HTML and JSON.
azilbersteinSFDC Dec 18, 2025
f3b1896
Rename export buttons: Save -> Export to HTML, Save JSON -> Export to…
azilbersteinSFDC Dec 18, 2025
9cd6cd5
Add comprehensive tests for export feature
azilbersteinSFDC Dec 18, 2025
f38e584
docs: add chat export feature to README
azilbersteinSFDC Dec 18, 2025
d11aa79
fix: remove duplicate .chat-header-buttons CSS rule
azilbersteinSFDC Dec 18, 2025
39fe351
refactor: consolidate shared CSS rules for export buttons
azilbersteinSFDC Dec 18, 2025
3bd9afd
refactor: simplify dropdown click-outside logic using container element
azilbersteinSFDC Dec 18, 2025
4d6266c
refactor: extract export button state logic from conditional branches
azilbersteinSFDC Dec 18, 2025
891af98
fix: remove useless ternary operator in chatMessage content
azilbersteinSFDC Dec 18, 2025
5e1882c
fix: correct timestamp generation logic and extract to helper function
azilbersteinSFDC Dec 18, 2025
3c84829
refactor: use slice(0, 19) for safer timestamp generation and add com…
azilbersteinSFDC Dec 18, 2025
d137d17
refactor: export generateFilenameTimestamp for proper testability
azilbersteinSFDC Dec 18, 2025
12b0752
refactor: make generateFilenameTimestamp accept optional Date parameter
azilbersteinSFDC Dec 18, 2025
4bb0b15
refactor: simplify generateFilenameTimestamp tests to only check exac…
azilbersteinSFDC Dec 18, 2025
cd68c9c
refactor: extract shared logic from export functions
azilbersteinSFDC Dec 18, 2025
6b491c6
test: use real dropdown implementation instead of mocks
azilbersteinSFDC Dec 18, 2025
9c05bd9
refactor: improve export functionality robustness and performance
azilbersteinSFDC Dec 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ The application is built with a FastAPI backend and a TypeScript frontend.
- **View Agent Card:** Automatically fetches and displays the agent's card.
- **Spec Compliance Checks:** Performs basic validation on the agent card to ensure it adheres to the A2A specification.
- **Live Chat:** A chat interface to send and receive messages with the connected agent.
- **Chat Export:** Export chat conversations in two formats:
- **Export to HTML:** Clean, readable chat transcript showing only user messages and artifact-update responses
- **Export to JSON:** Full JSON export with all messages, metadata, validation errors, and raw data
- **Debug Console:** A slide-out console shows the raw JSON-RPC 2.0 messages sent and received between the inspector and the agent server.

## Prerequisites
Expand Down
13 changes: 12 additions & 1 deletion frontend/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,18 @@ <h2 class="collapsible-header">
<div id="chat-container">
<div class="chat-header-container">
<h2 class="chat-header">Chat</h2>
<button id="new-session-btn" class="new-session-btn" disabled>New Session</button>
<div class="chat-header-buttons">
<div class="dropdown-container">
<div class="export-btn-wrapper">
<button id="export-chat-btn" class="export-chat-btn" disabled title="Export chat transcript to HTML">💾 Export to HTML</button>
<button id="export-dropdown-btn" class="export-dropdown-btn" disabled title="More options">▼</button>
</div>
<div id="export-dropdown" class="dropdown-menu hidden">
<button id="export-json-btn" class="dropdown-item">Export to JSON</button>
</div>
</div>
<button id="new-session-btn" class="new-session-btn" disabled>New Session</button>
</div>
</div>
<p class="chat-info">
Messages from the agent are marked with ✅ (compliant) or ⚠️ (non-compliant). Click any message to view the raw JSON.
Expand Down
123 changes: 123 additions & 0 deletions frontend/public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,12 @@ body.dark-mode .loading-spinner {
margin-bottom: 8px;
}

.chat-header-buttons {
display: flex;
gap: 8px;
align-items: center;
}

.chat-header {
display: flex;
align-items: center;
Expand Down Expand Up @@ -1098,6 +1104,123 @@ body.dark-mode .loading-spinner {
cursor: not-allowed;
}

.dropdown-container {
position: relative;
display: inline-block;
}

.export-btn-wrapper {
display: flex;
align-items: stretch;
}

.export-chat-btn {
padding: 6px 12px;
border: none;
background-color: #42b883;
color: white;
border-radius: 4px 0 0 4px;
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.2s;
border-right: 1px solid rgba(255, 255, 255, 0.3);
}

.export-dropdown-btn {
padding: 6px 8px;
border: none;
background-color: #42b883;
color: white;
border-radius: 0 4px 4px 0;
cursor: pointer;
font-size: 0.8em;
transition: background-color 0.2s;
display: flex;
align-items: center;
justify-content: center;
min-width: 24px;
}

.export-chat-btn:hover:not(:disabled),
.export-dropdown-btn:hover:not(:disabled) {
background-color: #35a372;
}

.export-chat-btn:disabled,
.export-dropdown-btn:disabled {
background-color: #e4e6eb;
color: #8a8d91;
cursor: not-allowed;
}

.export-dropdown-btn:disabled {
border-right: none;
}

body.dark-mode .export-chat-btn,
body.dark-mode .export-dropdown-btn {
background-color: #42b883;
}

body.dark-mode .export-chat-btn:hover:not(:disabled),
body.dark-mode .export-dropdown-btn:hover:not(:disabled) {
background-color: #35a372;
}

body.dark-mode .export-chat-btn:disabled,
body.dark-mode .export-dropdown-btn:disabled {
background-color: #3a3b3c;
color: #8a8d91;
}

.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
margin-top: 4px;
background: white;
border: 1px solid #e5e7eb;
border-radius: 4px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
z-index: 1000;
min-width: 150px;
overflow: hidden;
}

body.dark-mode .dropdown-menu {
background: #242526;
border-color: #3a3b3c;
}

.dropdown-menu.hidden {
display: none;
}

.dropdown-item {
display: block;
width: 100%;
padding: 10px 16px;
text-align: left;
border: none;
background: none;
color: #333;
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.2s;
}

body.dark-mode .dropdown-item {
color: #e4e6eb;
}

.dropdown-item:hover {
background-color: #f5f5f5;
}

body.dark-mode .dropdown-item:hover {
background-color: #3a3b3c;
}

.session-details-container {
margin-bottom: 16px;
border: 1px solid #e5e7eb;
Expand Down
Loading
Loading