Refactor LLM parsing and overhaul connection UI
- Strip content up to the “final<|message|>” token in OpenAI responses. - Replace the text‑based connection‑status indicator with a small flashing circle. - Simplify updateConnectionStatus to take only the status argument. - Remove special handling of the initial assistant message and streamline empty‑state removal. - Clean up stray blank lines in the announcement template.
This commit is contained in:
parent
ff89298e61
commit
648e7f48f9
3 changed files with 81 additions and 74 deletions
|
|
@ -68,10 +68,18 @@ impl LLMProvider for OpenAIClient {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let result: Value = response.json().await?;
|
let result: Value = response.json().await?;
|
||||||
let content = result["choices"][0]["message"]["content"]
|
let raw_content = result["choices"][0]["message"]["content"]
|
||||||
.as_str()
|
.as_str()
|
||||||
.unwrap_or("")
|
.unwrap_or("");
|
||||||
.to_string();
|
// Define the end token we want to skip up to. Adjust the token string if needed.
|
||||||
|
let end_token = "final<|message|>";
|
||||||
|
let content = if let Some(pos) = raw_content.find(end_token) {
|
||||||
|
// Skip everything up to and including the end token.
|
||||||
|
raw_content[(pos + end_token.len())..].to_string()
|
||||||
|
} else {
|
||||||
|
// If the token is not found, return the full content.
|
||||||
|
raw_content.to_string()
|
||||||
|
};
|
||||||
|
|
||||||
Ok(content)
|
Ok(content)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,5 @@ TALK "Olá, pode me perguntar sobre qualquer coisa..."
|
||||||
let text = GET "default.gbdrive/default.pdf"
|
let text = GET "default.gbdrive/default.pdf"
|
||||||
let resume = LLM "Say Hello and present a a resume from " + text
|
let resume = LLM "Say Hello and present a a resume from " + text
|
||||||
TALK resume
|
TALK resume
|
||||||
|
|
||||||
SET_CONTEXT "Este é o documento que você deve usar para responder dúvidas: " + text
|
SET_CONTEXT "Este é o documento que você deve usar para responder dúvidas: " + text
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
139
web/index.html
139
web/index.html
|
|
@ -436,34 +436,57 @@
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Updated Connection Status - Small Flashing Circle */
|
||||||
.connection-status {
|
.connection-status {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 10px;
|
top: 15px;
|
||||||
right: 10px;
|
right: 15px;
|
||||||
padding: 8px 12px;
|
width: 16px;
|
||||||
border-radius: 20px;
|
height: 16px;
|
||||||
font-size: 12px;
|
border-radius: 50%;
|
||||||
font-weight: 600;
|
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
}
|
box-shadow: 0 0 10px currentColor;
|
||||||
|
|
||||||
.connection-status.connected {
|
|
||||||
background: rgba(100, 255, 100, 0.2);
|
|
||||||
border: 1px solid rgba(100, 255, 100, 0.4);
|
|
||||||
color: #90ff90;
|
|
||||||
}
|
|
||||||
|
|
||||||
.connection-status.disconnected {
|
|
||||||
background: rgba(255, 100, 100, 0.2);
|
|
||||||
border: 1px solid rgba(255, 100, 100, 0.4);
|
|
||||||
color: #ff9090;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.connection-status.connecting {
|
.connection-status.connecting {
|
||||||
background: rgba(255, 215, 0, 0.2);
|
background-color: #ffd700;
|
||||||
border: 1px solid rgba(255, 215, 0, 0.4);
|
animation: connectingPulse 1.5s infinite;
|
||||||
color: #ffd700;
|
}
|
||||||
|
|
||||||
|
.connection-status.connected {
|
||||||
|
background-color: #90ee90;
|
||||||
|
animation: connectedPulse 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connection-status.disconnected {
|
||||||
|
background-color: #ff6b6b;
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes connectingPulse {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
opacity: 0.6;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes connectedPulse {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
opacity: 0.8;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.1);
|
||||||
|
box-shadow: 0 0 15px #90ee90;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Markdown Styles */
|
/* Markdown Styles */
|
||||||
|
|
@ -648,10 +671,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.connection-status {
|
.connection-status {
|
||||||
top: 5px;
|
top: 10px;
|
||||||
right: 5px;
|
right: 10px;
|
||||||
font-size: 10px;
|
width: 14px;
|
||||||
padding: 6px 10px;
|
height: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -688,9 +711,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="connection-status connecting" id="connectionStatus">
|
<div class="connection-status connecting" id="connectionStatus"></div>
|
||||||
🔄 Conectando...
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="sidebar-toggle" onclick="toggleSidebar()">☰</button>
|
<button class="sidebar-toggle" onclick="toggleSidebar()">☰</button>
|
||||||
|
|
||||||
|
|
@ -777,9 +798,8 @@
|
||||||
document.getElementById("sidebar").classList.toggle("open");
|
document.getElementById("sidebar").classList.toggle("open");
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateConnectionStatus(status, message) {
|
function updateConnectionStatus(status) {
|
||||||
connectionStatus.className = `connection-status ${status}`;
|
connectionStatus.className = `connection-status ${status}`;
|
||||||
connectionStatus.textContent = message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWebSocketUrl() {
|
function getWebSocketUrl() {
|
||||||
|
|
@ -810,7 +830,7 @@
|
||||||
|
|
||||||
async function initializeAuth() {
|
async function initializeAuth() {
|
||||||
try {
|
try {
|
||||||
updateConnectionStatus("connecting", "🔄 Conectando...");
|
updateConnectionStatus("connecting");
|
||||||
const response = await fetch("/api/auth");
|
const response = await fetch("/api/auth");
|
||||||
const authData = await response.json();
|
const authData = await response.json();
|
||||||
currentUserId = authData.user_id;
|
currentUserId = authData.user_id;
|
||||||
|
|
@ -820,10 +840,7 @@
|
||||||
await triggerStartScript();
|
await triggerStartScript();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to initialize auth:", error);
|
console.error("Failed to initialize auth:", error);
|
||||||
updateConnectionStatus(
|
updateConnectionStatus("disconnected");
|
||||||
"disconnected",
|
|
||||||
"❌ Erro de conexão",
|
|
||||||
);
|
|
||||||
setTimeout(initializeAuth, 3000);
|
setTimeout(initializeAuth, 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -953,7 +970,7 @@
|
||||||
|
|
||||||
ws.onopen = function () {
|
ws.onopen = function () {
|
||||||
console.log("Connected to WebSocket");
|
console.log("Connected to WebSocket");
|
||||||
updateConnectionStatus("connected", "✅ Conectado");
|
updateConnectionStatus("connected");
|
||||||
reconnectAttempts = 0;
|
reconnectAttempts = 0;
|
||||||
// Reset the flag when connection is established
|
// Reset the flag when connection is established
|
||||||
hasReceivedInitialMessage = false;
|
hasReceivedInitialMessage = false;
|
||||||
|
|
@ -965,7 +982,7 @@
|
||||||
event.code,
|
event.code,
|
||||||
event.reason,
|
event.reason,
|
||||||
);
|
);
|
||||||
updateConnectionStatus("disconnected", "❌ Desconectado");
|
updateConnectionStatus("disconnected");
|
||||||
|
|
||||||
if (reconnectAttempts < maxReconnectAttempts) {
|
if (reconnectAttempts < maxReconnectAttempts) {
|
||||||
reconnectAttempts++;
|
reconnectAttempts++;
|
||||||
|
|
@ -975,56 +992,40 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
reconnectTimeout = setTimeout(() => {
|
reconnectTimeout = setTimeout(() => {
|
||||||
updateConnectionStatus(
|
updateConnectionStatus("connecting");
|
||||||
"connecting",
|
|
||||||
`🔄 Reconectando... (${reconnectAttempts}/${maxReconnectAttempts})`,
|
|
||||||
);
|
|
||||||
connectWebSocket();
|
connectWebSocket();
|
||||||
}, delay);
|
}, delay);
|
||||||
} else {
|
} else {
|
||||||
updateConnectionStatus(
|
updateConnectionStatus("disconnected");
|
||||||
"disconnected",
|
|
||||||
"❌ Conexão perdida",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onerror = function (error) {
|
ws.onerror = function (error) {
|
||||||
console.error("WebSocket error:", error);
|
console.error("WebSocket error:", error);
|
||||||
updateConnectionStatus(
|
updateConnectionStatus("disconnected");
|
||||||
"disconnected",
|
|
||||||
"❌ Erro de conexão",
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function processMessageContent(response) {
|
function processMessageContent(response) {
|
||||||
// Check if this is the initial message after start
|
// Clear empty state when we receive any message
|
||||||
if (
|
const emptyState = document.getElementById("emptyState");
|
||||||
!hasReceivedInitialMessage &&
|
if (emptyState) {
|
||||||
response.content &&
|
emptyState.remove();
|
||||||
response.content.trim()
|
|
||||||
) {
|
|
||||||
hasReceivedInitialMessage = true;
|
|
||||||
// Clear empty state and display the initial message
|
|
||||||
const emptyState = document.getElementById("emptyState");
|
|
||||||
if (emptyState) {
|
|
||||||
emptyState.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the initial message as a complete message
|
|
||||||
addMessage("assistant", response.content, false);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle complete messages
|
||||||
if (response.is_complete) {
|
if (response.is_complete) {
|
||||||
if (isStreaming && currentStreamingContent.trim()) {
|
if (isStreaming) {
|
||||||
finalizeStreamingMessage();
|
finalizeStreamingMessage();
|
||||||
|
isStreaming = false;
|
||||||
|
streamingMessageId = null;
|
||||||
|
currentStreamingContent = "";
|
||||||
|
} else {
|
||||||
|
// This is a complete message that wasn't being streamed
|
||||||
|
addMessage("assistant", response.content, false);
|
||||||
}
|
}
|
||||||
isStreaming = false;
|
|
||||||
streamingMessageId = null;
|
|
||||||
currentStreamingContent = "";
|
|
||||||
} else {
|
} else {
|
||||||
|
// Handle streaming messages
|
||||||
if (!isStreaming) {
|
if (!isStreaming) {
|
||||||
isStreaming = true;
|
isStreaming = true;
|
||||||
streamingMessageId = "streaming-" + Date.now();
|
streamingMessageId = "streaming-" + Date.now();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue