Skip to content

Commit

Permalink
checkpoint: output debug logs in chat transcript
Browse files Browse the repository at this point in the history
  • Loading branch information
lublagg committed Dec 2, 2024
1 parent fb77120 commit 68449ae
Show file tree
Hide file tree
Showing 13 changed files with 641 additions and 48 deletions.
13 changes: 13 additions & 0 deletions src/components/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,17 @@
position: absolute;
width: 1px;
}

.show-debug-controls {
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 5px;
font-size: .75em;
margin-top: 10px;
input:hover {
cursor: pointer;
}
}
}
31 changes: 29 additions & 2 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export const App = observer(() => {
const [keyboardShortcutEnabled, setKeyboardShortcutEnabled] = useState(isShortcutEnabled);
const shortcutKeys = localStorage.getItem("keyboardShortcutKeys") || "ctrl+?";
const [keyboardShortcutKeys, setKeyboardShortcutKeys] = useState(shortcutKeys);
const url = new URL(window.location.href);
const params = new URLSearchParams(url.search);
const hasDebugParams = params.has("debug");
const [showDebugLog, setShowDebugLog] = useState(hasDebugParams);

useEffect(() => {
initializePlugin({pluginName: kPluginName, version: kVersion, dimensions: kInitialDimensions});
Expand Down Expand Up @@ -59,7 +63,7 @@ export const App = observer(() => {
}

const handleChatInputSubmit = async (messageText: string) => {
transcriptStore.addMessage(USER_SPEAKER, messageText);
transcriptStore.addMessage(USER_SPEAKER, {content: messageText});
assistantStore.handleMessageSubmit(messageText);
};

Expand All @@ -71,7 +75,30 @@ export const App = observer(() => {
<span>(Data Analysis through Voice and Artificial Intelligence)</span>
</h1>
</header>
<ChatTranscriptComponent chatTranscript={transcriptStore} />
<ChatTranscriptComponent
chatTranscript={transcriptStore}
showDebugLog={showDebugLog}
/>
{hasDebugParams &&
<div className="show-debug-controls">
<label htmlFor="debug-log-toggle">
Show Debug Log:
</label>
<input
type="checkbox"
id="debug-log-toggle"
name="ShowDebugLog"
aria-checked={showDebugLog}
checked={showDebugLog}
onChange={() => setShowDebugLog(!showDebugLog)}
onKeyDown={(e) => {
if (e.key === "Enter") {
setShowDebugLog(!showDebugLog);
}
}}
/>
</div>
}
<ChatInputComponent
keyboardShortcutEnabled={keyboardShortcutEnabled}
shortcutKeys={keyboardShortcutKeys}
Expand Down
64 changes: 64 additions & 0 deletions src/components/chat-transcript-message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { useState } from "react";
import Markdown from "react-markdown";
import { DEBUG_SPEAKER } from "../constants";
import { ChatMessage } from "../types";

interface IProps {
message: ChatMessage;
showDebugLog: boolean;
}

export const ChatTranscriptMessage = ({message, showDebugLog}: IProps) => {
const { speaker, messageContent, timestamp } = message;
const [showMessage, setShowMessage] = useState(false);

if (speaker === DEBUG_SPEAKER && !showDebugLog) {
return null;
}

const renderDebugPreview = () => {
const expandedClass = showMessage ? "expanded" : "collapsed";
return (
<div className={`debug-message-wrapper ${expandedClass}`}>
<div className="header">
<button
onClick={() => setShowMessage(!showMessage)}
>
<span>{showMessage ? "Collapse content" : "Expand content"}</span>
</button>
<h4>{messageContent.description}:</h4>
</div>
<pre
aria-expanded={showMessage}
>
{messageContent.content}
</pre>
</div>
);
};

const speakerClass = speaker === DEBUG_SPEAKER ? "debug" : speaker.toLowerCase();

return (
<section
aria-label={`${speaker} at ${timestamp}`}
className={`chat-transcript__message ${speakerClass}`}
data-testid="chat-message"
role="listitem"
>
<h3 aria-label="speaker" data-testid="chat-message-speaker">
{speaker}
</h3>
<div
aria-label="message"
className={`chat-message-content ${speakerClass}`}
data-testid="chat-message-content"
>
{speaker === DEBUG_SPEAKER ?
renderDebugPreview() :
<Markdown>{messageContent.content}</Markdown>
}
</div>
</section>
);
};
77 changes: 74 additions & 3 deletions src/components/chat-transcript.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
margin: 0;
padding: 8px 10px;

&:nth-child(odd) {
&.davai {
background: $light-teal-2;
}

&.debug {
background: lightyellow;
}

h3, li, p {
font-size: .75rem;
line-height: 17px;
Expand All @@ -34,14 +38,81 @@
font-size: .75rem;
}
.chat-message-content {
&.chat-message-content--user {
&.user {
white-space: pre-line; // maintain line breaks
}
&.chat-message-content--davai {
&.davai {
pre {
white-space: normal;
}
}
&.debug {
.debug-message-wrapper {
display: flex;
padding: 5px;
// align-items: center;
gap: 10px;

.header {
display: flex;
align-items: center;
word-break: none;
white-space: nowrap;
h4 {
font-size: .75rem;
margin: 0;
padding: 0;
}
}

&.expanded{
flex-direction: column;
align-items: flex-start;
gap: 0px;
pre {
white-space: pre-wrap;
word-break: break-word;
}
}

&.collapsed{
button {
&:before {
transform: rotate(-90deg);
}
}
pre {
word-break: none;
overflow: hidden;
white-space: nowrap;
margin: 0;
}
}

button {
appearance: none;
background-color: transparent;
border: 0;
position: relative;
height: auto;
padding: 0;
margin: 0;
width: 20px;
span {
display: block;
text-indent: -99999px;
}
&:before {
display: block;
position: absolute;
content: "\25BC";
color: $dark-gray;
top: 0;
left: 0;
}
}
}
}
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/components/chat-transcript.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ describe("test chat transcript component", () => {
const chatTranscript = {
messages: [
{
content: "Hello. How can I help you today?",
messageContent: {content: "Hello. How can I help you today?"},
speaker: "DAVAI",
timestamp: "2021-07-01T12:00:00Z"
},
{
content: "Tell me about the data!",
messageContent: {content: "Tell me about the data!"},
speaker: "User",
timestamp: "2021-07-01T12:00:05Z"
}
]
};

it("renders a chat transcript that lists all chat messages", () => {
render(<ChatTranscriptComponent chatTranscript={chatTranscript} />);
render(<ChatTranscriptComponent chatTranscript={chatTranscript} showDebugLog={false}/>);

const transcript = screen.getByTestId("chat-transcript");
const messagesContainer = screen.getByTestId("chat-transcript__messages");
Expand All @@ -39,7 +39,7 @@ describe("test chat transcript component", () => {

const content = within(message).getByTestId("chat-message-content");
expect(content).toHaveAttribute("aria-label", "message");
expect(content).toHaveTextContent(chatTranscript.messages[index].content);
expect(content).toHaveTextContent(chatTranscript.messages[index].messageContent.content);
});
});
});
32 changes: 8 additions & 24 deletions src/components/chat-transcript.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, { useRef, useEffect } from "react";
import { observer } from "mobx-react-lite";
import Markdown from "react-markdown";
import { DAVAI_SPEAKER } from "../constants";
import { ChatTranscriptMessage } from "./chat-transcript-message";
import { ChatTranscript, ChatMessage } from "../types";

import "./chat-transcript.scss";

interface IProps {
chatTranscript: ChatTranscript;
showDebugLog: boolean;
}

export const ChatTranscriptComponent = observer(({chatTranscript}: IProps) => {
export const ChatTranscriptComponent = observer(({chatTranscript, showDebugLog}: IProps) => {
const chatTranscriptRef = useRef<HTMLElement>(null);

useEffect(() => {
Expand All @@ -33,28 +33,12 @@ export const ChatTranscriptComponent = observer(({chatTranscript}: IProps) => {
role="list"
>
{chatTranscript.messages.map((message: ChatMessage) => {
const messageContentClass = message.speaker === DAVAI_SPEAKER
? "chat-message-content--davai"
: "chat-message-content--user";
return (
<section
aria-label={`${message.speaker} at ${message.timestamp}`}
className="chat-transcript__message"
data-testid="chat-message"
key={message.timestamp}
role="listitem"
>
<h3 aria-label="speaker" data-testid="chat-message-speaker">
{message.speaker}
</h3>
<div
aria-label="message"
className={`chat-message-content ${messageContentClass}`}
data-testid="chat-message-content"
>
<Markdown>{message.content}</Markdown>
</div>
</section>
<ChatTranscriptMessage
key={`${message.timestamp}-${message.speaker}`}
message={message}
showDebugLog={showDebugLog}
/>
);
})}
</section>
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const DEBUG_SPEAKER = "Debug Log";
export const DAVAI_SPEAKER = "DAVAI";
export const USER_SPEAKER = "User";
Loading

0 comments on commit 68449ae

Please sign in to comment.