Update static/frontend.html
Browse files- static/frontend.html +72 -71
static/frontend.html
CHANGED
|
@@ -6,15 +6,10 @@
|
|
| 6 |
<title>Code Assistant Agent</title>
|
| 7 |
<style>
|
| 8 |
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background-color: #f0f2f5; color: #333; }
|
| 9 |
-
.container { max-width:
|
| 10 |
-
.main-content { flex: 2; min-width: 550px; }
|
| 11 |
-
.state-panel { flex: 1; background-color: #f8f8f8; padding: 15px; border-radius: 8px; border: 1px solid #e0e0e0; max-height: 700px; overflow-y: auto; }
|
| 12 |
-
|
| 13 |
h1 { color: #1f7cff; text-align: center; margin-bottom: 25px; font-weight: 600; }
|
| 14 |
-
h2 { border-bottom: 2px solid #ddd; padding-bottom: 5px; margin-top: 30px; font-size: 1.2em; }
|
| 15 |
-
|
| 16 |
#chat-window {
|
| 17 |
-
height:
|
| 18 |
overflow-y: scroll;
|
| 19 |
border: 1px solid #ddd;
|
| 20 |
padding: 15px;
|
|
@@ -23,7 +18,11 @@
|
|
| 23 |
background-color: #e9eff4;
|
| 24 |
}
|
| 25 |
|
| 26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
.message {
|
| 28 |
padding: 10px 15px;
|
| 29 |
border-radius: 18px;
|
|
@@ -33,16 +32,16 @@
|
|
| 33 |
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
| 34 |
}
|
| 35 |
.user {
|
| 36 |
-
background-color: #1f7cff;
|
| 37 |
color: white;
|
| 38 |
-
margin-left: auto;
|
| 39 |
-
border-bottom-right-radius: 4px;
|
| 40 |
}
|
| 41 |
.assistant {
|
| 42 |
background-color: #ffffff;
|
| 43 |
border: 1px solid #c9d6de;
|
| 44 |
color: #333;
|
| 45 |
-
margin-right: auto;
|
| 46 |
border-bottom-left-radius: 4px;
|
| 47 |
text-align: left;
|
| 48 |
}
|
|
@@ -52,6 +51,8 @@
|
|
| 52 |
#send-button { padding: 10px 20px; background-color: #1f7cff; color: white; border: none; border-radius: 6px; cursor: pointer; transition: background-color 0.3s; }
|
| 53 |
#send-button:hover { background-color: #165bb0; }
|
| 54 |
|
|
|
|
|
|
|
| 55 |
pre {
|
| 56 |
background-color: #272822;
|
| 57 |
color: #f8f8f2;
|
|
@@ -85,55 +86,53 @@
|
|
| 85 |
.bookmark-btn { background-color: #28a745; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; transition: background-color 0.3s; font-size: 0.8em; }
|
| 86 |
.bookmark-btn:hover { background-color: #1e7e34; }
|
| 87 |
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
#
|
| 91 |
-
|
| 92 |
-
|
|
|
|
| 93 |
</style>
|
| 94 |
</head>
|
| 95 |
<body>
|
| 96 |
<div class="container">
|
| 97 |
-
<
|
| 98 |
-
<h1>Code Assistant Agent 🤖</h1>
|
| 99 |
|
| 100 |
-
|
| 101 |
-
|
|
|
|
|
|
|
| 102 |
|
| 103 |
-
|
| 104 |
-
<input type="text" id="user-input" placeholder="Ask about code, concepts, or bugs..." onkeypress="if(event.key === 'Enter') sendMessage()">
|
| 105 |
-
<button id="send-button" onclick="sendMessage()">Send</button>
|
| 106 |
</div>
|
| 107 |
|
| 108 |
-
|
| 109 |
-
<input type="text" id="
|
| 110 |
-
<
|
| 111 |
-
</ul>
|
| 112 |
-
</div>
|
| 113 |
-
|
| 114 |
-
<div class="state-panel">
|
| 115 |
-
<h2>Current Session State</h2>
|
| 116 |
-
<p>This is the full JSON object sent/received on every turn, ensuring context propagation.</p>
|
| 117 |
-
<div id="state-info">
|
| 118 |
-
<pre id="state-json-display">{}</pre>
|
| 119 |
-
</div>
|
| 120 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
</div>
|
| 122 |
|
| 123 |
<script>
|
| 124 |
-
//
|
|
|
|
|
|
|
|
|
|
| 125 |
let assistantState = {
|
| 126 |
conversationSummary: "",
|
| 127 |
language: "Python",
|
| 128 |
-
taggedReplies: []
|
| 129 |
-
fullChatHistory: [] // New, mandatory field for full context
|
| 130 |
};
|
| 131 |
const apiUrl = '/chat';
|
| 132 |
const tagUrl = '/tag_reply';
|
| 133 |
|
| 134 |
document.addEventListener('DOMContentLoaded', () => {
|
| 135 |
updateStateInfo();
|
| 136 |
-
// Initial greeting
|
| 137 |
appendMessage({ role: 'assistant', content: "Hello! I'm your Code Assistant. What programming language are you working in today?" });
|
| 138 |
});
|
| 139 |
|
|
@@ -145,41 +144,49 @@
|
|
| 145 |
|
| 146 |
if (!userMessage) return;
|
| 147 |
|
| 148 |
-
// 1.
|
| 149 |
const userMsgObj = { role: 'user', content: userMessage };
|
| 150 |
-
|
| 151 |
-
appendMessage(userMsgObj);
|
| 152 |
|
|
|
|
| 153 |
inputElement.value = '';
|
| 154 |
|
| 155 |
try {
|
| 156 |
-
// 2. Send the ENTIRE assistantState (which includes the full history)
|
| 157 |
const response = await fetch(apiUrl, {
|
| 158 |
method: 'POST',
|
| 159 |
headers: { 'Content-Type': 'application/json' },
|
| 160 |
-
body: JSON.stringify({
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
});
|
| 162 |
|
| 163 |
if (!response.ok) {
|
|
|
|
|
|
|
| 164 |
throw new Error(`HTTP error! status: ${response.status}`);
|
| 165 |
}
|
| 166 |
|
| 167 |
const data = await response.json();
|
| 168 |
|
| 169 |
-
//
|
| 170 |
assistantState = data.updated_state;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
|
| 172 |
-
// 4.
|
| 173 |
-
|
| 174 |
role: 'assistant',
|
| 175 |
content: data.assistant_reply,
|
| 176 |
suggestedTags: data.suggested_tags
|
| 177 |
-
};
|
| 178 |
|
| 179 |
-
// 5. Add assistant reply to local history (for next request)
|
| 180 |
-
assistantState.fullChatHistory.push({ role: 'assistant', content: data.assistant_reply });
|
| 181 |
-
|
| 182 |
-
appendMessage(assistantReplyObj);
|
| 183 |
updateStateInfo();
|
| 184 |
|
| 185 |
} catch (error) {
|
|
@@ -192,10 +199,10 @@
|
|
| 192 |
|
| 193 |
function appendMessage(msg) {
|
| 194 |
const chatWindow = document.getElementById('chat-window');
|
|
|
|
|
|
|
|
|
|
| 195 |
const msgDiv = document.createElement('div');
|
| 196 |
-
const rowDiv = document.createElement('div');
|
| 197 |
-
|
| 198 |
-
rowDiv.className = 'message-row';
|
| 199 |
msgDiv.className = `message ${msg.role}`;
|
| 200 |
|
| 201 |
let content = msg.content;
|
|
@@ -207,9 +214,12 @@
|
|
| 207 |
});
|
| 208 |
|
| 209 |
msgDiv.innerHTML = content;
|
|
|
|
|
|
|
| 210 |
|
| 211 |
-
|
| 212 |
-
|
|
|
|
| 213 |
const tagArea = document.createElement('div');
|
| 214 |
tagArea.className = 'tag-area';
|
| 215 |
tagArea.innerHTML = 'Tags: ';
|
|
@@ -230,25 +240,17 @@
|
|
| 230 |
tagArea.appendChild(bookmarkBtn);
|
| 231 |
msgDiv.appendChild(tagArea);
|
| 232 |
}
|
| 233 |
-
|
| 234 |
-
rowDiv.appendChild(msgDiv);
|
| 235 |
-
chatWindow.appendChild(rowDiv);
|
| 236 |
chatWindow.scrollTop = chatWindow.scrollHeight;
|
| 237 |
}
|
| 238 |
|
| 239 |
function updateStateInfo() {
|
|
|
|
| 240 |
document.getElementById('tagged-count').textContent = assistantState.taggedReplies.length;
|
| 241 |
-
|
| 242 |
-
// Display the full JSON state for context verification
|
| 243 |
-
const stateDisplay = { ...assistantState };
|
| 244 |
-
// Truncate history for cleaner display
|
| 245 |
-
stateDisplay.fullChatHistory = stateDisplay.fullChatHistory.slice(-5); // Show last 5 turns
|
| 246 |
-
|
| 247 |
-
document.getElementById('state-json-display').textContent = JSON.stringify(stateDisplay, null, 2);
|
| 248 |
filterReplies(); // Refresh the bookmark list
|
| 249 |
}
|
| 250 |
|
| 251 |
-
// --- Bookmarking and Tagging Logic
|
| 252 |
|
| 253 |
async function saveReply(replyContent, tagsString, buttonElement) {
|
| 254 |
const tags = tagsString.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0);
|
|
@@ -259,7 +261,6 @@
|
|
| 259 |
}
|
| 260 |
|
| 261 |
try {
|
| 262 |
-
// Send the current state along with the new reply to tag
|
| 263 |
const response = await fetch(tagUrl, {
|
| 264 |
method: 'POST',
|
| 265 |
headers: { 'Content-Type': 'application/json' },
|
|
@@ -317,4 +318,4 @@
|
|
| 317 |
}
|
| 318 |
</script>
|
| 319 |
</body>
|
| 320 |
-
</html>
|
|
|
|
| 6 |
<title>Code Assistant Agent</title>
|
| 7 |
<style>
|
| 8 |
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background-color: #f0f2f5; color: #333; }
|
| 9 |
+
.container { max-width: 850px; margin: auto; background: #fff; padding: 30px; border-radius: 12px; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1); }
|
|
|
|
|
|
|
|
|
|
| 10 |
h1 { color: #1f7cff; text-align: center; margin-bottom: 25px; font-weight: 600; }
|
|
|
|
|
|
|
| 11 |
#chat-window {
|
| 12 |
+
height: 400px;
|
| 13 |
overflow-y: scroll;
|
| 14 |
border: 1px solid #ddd;
|
| 15 |
padding: 15px;
|
|
|
|
| 18 |
background-color: #e9eff4;
|
| 19 |
}
|
| 20 |
|
| 21 |
+
/* NEW STRUCTURE FOR CHAT BUBBLES */
|
| 22 |
+
.message-row {
|
| 23 |
+
display: flex;
|
| 24 |
+
margin-bottom: 15px;
|
| 25 |
+
}
|
| 26 |
.message {
|
| 27 |
padding: 10px 15px;
|
| 28 |
border-radius: 18px;
|
|
|
|
| 32 |
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
| 33 |
}
|
| 34 |
.user {
|
| 35 |
+
background-color: #1f7cff; /* Bright blue for user */
|
| 36 |
color: white;
|
| 37 |
+
margin-left: auto; /* Pushes to the right */
|
| 38 |
+
border-bottom-right-radius: 4px; /* Sharper corner on user's side */
|
| 39 |
}
|
| 40 |
.assistant {
|
| 41 |
background-color: #ffffff;
|
| 42 |
border: 1px solid #c9d6de;
|
| 43 |
color: #333;
|
| 44 |
+
margin-right: auto; /* Keeps it on the left */
|
| 45 |
border-bottom-left-radius: 4px;
|
| 46 |
text-align: left;
|
| 47 |
}
|
|
|
|
| 51 |
#send-button { padding: 10px 20px; background-color: #1f7cff; color: white; border: none; border-radius: 6px; cursor: pointer; transition: background-color 0.3s; }
|
| 52 |
#send-button:hover { background-color: #165bb0; }
|
| 53 |
|
| 54 |
+
#state-info { padding: 15px; background-color: #e6f0ff; border-left: 5px solid #1f7cff; border-radius: 4px; font-size: 0.9em; margin-bottom: 25px; display: flex; justify-content: space-between; align-items: center; }
|
| 55 |
+
|
| 56 |
pre {
|
| 57 |
background-color: #272822;
|
| 58 |
color: #f8f8f2;
|
|
|
|
| 86 |
.bookmark-btn { background-color: #28a745; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; transition: background-color 0.3s; font-size: 0.8em; }
|
| 87 |
.bookmark-btn:hover { background-color: #1e7e34; }
|
| 88 |
|
| 89 |
+
/* Bookmarked Replies Styling */
|
| 90 |
+
h2 { border-bottom: 2px solid #ddd; padding-bottom: 5px; margin-top: 30px; }
|
| 91 |
+
#tag-search { padding: 10px; border: 1px solid #ccc; border-radius: 4px; width: 100%; margin-bottom: 15px; }
|
| 92 |
+
.tagged-replies-list { list-style: none; padding: 0; }
|
| 93 |
+
.tagged-replies-list li { border: 1px solid #f0f0f0; background: #fafafa; padding: 15px; border-radius: 6px; margin-bottom: 10px; }
|
| 94 |
+
.tagged-replies-list li p { margin: 0 0 5px 0; }
|
| 95 |
</style>
|
| 96 |
</head>
|
| 97 |
<body>
|
| 98 |
<div class="container">
|
| 99 |
+
<h1>Code Assistant Agent 🤖</h1>
|
|
|
|
| 100 |
|
| 101 |
+
<div id="state-info">
|
| 102 |
+
Current Language: <span id="current-language">Python</span>
|
| 103 |
+
| Total Bookmarked Replies: <span id="tagged-count">0</span>
|
| 104 |
+
</div>
|
| 105 |
|
| 106 |
+
<div id="chat-window">
|
|
|
|
|
|
|
| 107 |
</div>
|
| 108 |
|
| 109 |
+
<div id="input-container">
|
| 110 |
+
<input type="text" id="user-input" placeholder="Ask about code, concepts, or bugs..." onkeypress="if(event.key === 'Enter') sendMessage()">
|
| 111 |
+
<button id="send-button" onclick="sendMessage()">Send</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
</div>
|
| 113 |
+
|
| 114 |
+
<h2>Bookmarked Replies</h2>
|
| 115 |
+
<input type="text" id="tag-search" placeholder="Search by Tag (e.g., Python, Debugging)" oninput="filterReplies()">
|
| 116 |
+
<ul id="tagged-replies-display" class="tagged-replies-list">
|
| 117 |
+
</ul>
|
| 118 |
</div>
|
| 119 |
|
| 120 |
<script>
|
| 121 |
+
// Store the full conversation history (Crucial for context)
|
| 122 |
+
let chatHistory = [];
|
| 123 |
+
|
| 124 |
+
// Initial state structure matching the backend
|
| 125 |
let assistantState = {
|
| 126 |
conversationSummary: "",
|
| 127 |
language: "Python",
|
| 128 |
+
taggedReplies: []
|
|
|
|
| 129 |
};
|
| 130 |
const apiUrl = '/chat';
|
| 131 |
const tagUrl = '/tag_reply';
|
| 132 |
|
| 133 |
document.addEventListener('DOMContentLoaded', () => {
|
| 134 |
updateStateInfo();
|
| 135 |
+
// Initial greeting (display only, not pushed to chatHistory)
|
| 136 |
appendMessage({ role: 'assistant', content: "Hello! I'm your Code Assistant. What programming language are you working in today?" });
|
| 137 |
});
|
| 138 |
|
|
|
|
| 144 |
|
| 145 |
if (!userMessage) return;
|
| 146 |
|
| 147 |
+
// 1. Capture and add the user message to history
|
| 148 |
const userMsgObj = { role: 'user', content: userMessage };
|
| 149 |
+
chatHistory.push(userMsgObj);
|
|
|
|
| 150 |
|
| 151 |
+
appendMessage(userMsgObj);
|
| 152 |
inputElement.value = '';
|
| 153 |
|
| 154 |
try {
|
|
|
|
| 155 |
const response = await fetch(apiUrl, {
|
| 156 |
method: 'POST',
|
| 157 |
headers: { 'Content-Type': 'application/json' },
|
| 158 |
+
body: JSON.stringify({
|
| 159 |
+
// CRUCIAL FIX: Send the complete chatHistory array
|
| 160 |
+
chat_history: chatHistory,
|
| 161 |
+
assistant_state: assistantState
|
| 162 |
+
})
|
| 163 |
});
|
| 164 |
|
| 165 |
if (!response.ok) {
|
| 166 |
+
// Remove the user message from history if the request failed
|
| 167 |
+
chatHistory.pop();
|
| 168 |
throw new Error(`HTTP error! status: ${response.status}`);
|
| 169 |
}
|
| 170 |
|
| 171 |
const data = await response.json();
|
| 172 |
|
| 173 |
+
// 2. Update state
|
| 174 |
assistantState = data.updated_state;
|
| 175 |
+
|
| 176 |
+
// 3. Capture and add the assistant reply to history
|
| 177 |
+
const assistantMsgObj = {
|
| 178 |
+
role: 'assistant',
|
| 179 |
+
content: data.assistant_reply
|
| 180 |
+
};
|
| 181 |
+
chatHistory.push(assistantMsgObj); // <-- Add assistant's reply to history
|
| 182 |
|
| 183 |
+
// 4. Display the reply
|
| 184 |
+
appendMessage({
|
| 185 |
role: 'assistant',
|
| 186 |
content: data.assistant_reply,
|
| 187 |
suggestedTags: data.suggested_tags
|
| 188 |
+
});
|
| 189 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
updateStateInfo();
|
| 191 |
|
| 192 |
} catch (error) {
|
|
|
|
| 199 |
|
| 200 |
function appendMessage(msg) {
|
| 201 |
const chatWindow = document.getElementById('chat-window');
|
| 202 |
+
const messageRow = document.createElement('div');
|
| 203 |
+
messageRow.className = 'message-row';
|
| 204 |
+
|
| 205 |
const msgDiv = document.createElement('div');
|
|
|
|
|
|
|
|
|
|
| 206 |
msgDiv.className = `message ${msg.role}`;
|
| 207 |
|
| 208 |
let content = msg.content;
|
|
|
|
| 214 |
});
|
| 215 |
|
| 216 |
msgDiv.innerHTML = content;
|
| 217 |
+
messageRow.appendChild(msgDiv);
|
| 218 |
+
chatWindow.appendChild(messageRow);
|
| 219 |
|
| 220 |
+
|
| 221 |
+
// Add Tagging UI for assistant replies
|
| 222 |
+
if (msg.role === 'assistant') {
|
| 223 |
const tagArea = document.createElement('div');
|
| 224 |
tagArea.className = 'tag-area';
|
| 225 |
tagArea.innerHTML = 'Tags: ';
|
|
|
|
| 240 |
tagArea.appendChild(bookmarkBtn);
|
| 241 |
msgDiv.appendChild(tagArea);
|
| 242 |
}
|
| 243 |
+
|
|
|
|
|
|
|
| 244 |
chatWindow.scrollTop = chatWindow.scrollHeight;
|
| 245 |
}
|
| 246 |
|
| 247 |
function updateStateInfo() {
|
| 248 |
+
document.getElementById('current-language').textContent = assistantState.language;
|
| 249 |
document.getElementById('tagged-count').textContent = assistantState.taggedReplies.length;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
filterReplies(); // Refresh the bookmark list
|
| 251 |
}
|
| 252 |
|
| 253 |
+
// --- Bookmarking and Tagging Logic ---
|
| 254 |
|
| 255 |
async function saveReply(replyContent, tagsString, buttonElement) {
|
| 256 |
const tags = tagsString.split(',').map(tag => tag.trim()).filter(tag => tag.length > 0);
|
|
|
|
| 261 |
}
|
| 262 |
|
| 263 |
try {
|
|
|
|
| 264 |
const response = await fetch(tagUrl, {
|
| 265 |
method: 'POST',
|
| 266 |
headers: { 'Content-Type': 'application/json' },
|
|
|
|
| 318 |
}
|
| 319 |
</script>
|
| 320 |
</body>
|
| 321 |
+
</html>
|