fix: Ollama click handler and stream completion
- Fixed sidebar Ollama Cloud section to always open modal on click - Improved stream handling with proper buffer flush on end - Added 120s timeout for Ollama requests - Added better logging for debugging - Fixed activeRequest cleanup on errors
This commit is contained in:
@@ -62,10 +62,13 @@ export async function streamChat(messages, model = 'gpt-oss:120b', onChunk, onCo
|
|||||||
activeRequest = req;
|
activeRequest = req;
|
||||||
let fullResponse = '';
|
let fullResponse = '';
|
||||||
|
|
||||||
|
log(`Response status: ${res.statusCode}`);
|
||||||
|
|
||||||
if (res.statusCode !== 200) {
|
if (res.statusCode !== 200) {
|
||||||
let errBody = '';
|
let errBody = '';
|
||||||
res.on('data', (c) => errBody += c.toString());
|
res.on('data', (c) => errBody += c.toString());
|
||||||
res.on('end', () => {
|
res.on('end', () => {
|
||||||
|
log(`API Error: ${errBody}`);
|
||||||
onError(new Error(`Ollama API Error ${res.statusCode}: ${errBody}`));
|
onError(new Error(`Ollama API Error ${res.statusCode}: ${errBody}`));
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -77,7 +80,7 @@ export async function streamChat(messages, model = 'gpt-oss:120b', onChunk, onCo
|
|||||||
res.on('data', (chunk) => {
|
res.on('data', (chunk) => {
|
||||||
buffer += chunk;
|
buffer += chunk;
|
||||||
const lines = buffer.split('\n');
|
const lines = buffer.split('\n');
|
||||||
buffer = lines.pop();
|
buffer = lines.pop(); // Keep incomplete line in buffer
|
||||||
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
if (!line.trim()) continue;
|
if (!line.trim()) continue;
|
||||||
@@ -88,22 +91,53 @@ export async function streamChat(messages, model = 'gpt-oss:120b', onChunk, onCo
|
|||||||
fullResponse += content;
|
fullResponse += content;
|
||||||
onChunk(content);
|
onChunk(content);
|
||||||
}
|
}
|
||||||
if (parsed.done) {
|
// Check if this is the final message
|
||||||
// Request is done according to Ollama API
|
if (parsed.done === true) {
|
||||||
|
log('Received done signal from Ollama');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Ignore malformed JSON chunks
|
// Ignore malformed JSON chunks
|
||||||
|
log(`Parse error (ignored): ${e.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res.on('end', () => {
|
res.on('end', () => {
|
||||||
|
// Process any remaining data in buffer
|
||||||
|
if (buffer.trim()) {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(buffer);
|
||||||
|
const content = parsed.message?.content || '';
|
||||||
|
if (content) {
|
||||||
|
fullResponse += content;
|
||||||
|
onChunk(content);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Final chunk wasn't valid JSON, that's fine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log(`Stream complete. Total response length: ${fullResponse.length}`);
|
||||||
onComplete(fullResponse);
|
onComplete(fullResponse);
|
||||||
|
activeRequest = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
res.on('error', (e) => {
|
||||||
|
log(`Response error: ${e.message}`);
|
||||||
|
onError(e);
|
||||||
|
activeRequest = null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on('error', (e) => {
|
req.on('error', (e) => {
|
||||||
|
log(`Request error: ${e.message}`);
|
||||||
onError(e);
|
onError(e);
|
||||||
|
activeRequest = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.setTimeout(120000, () => {
|
||||||
|
log('Request timeout after 120s');
|
||||||
|
req.destroy();
|
||||||
|
onError(new Error('Ollama Cloud request timeout'));
|
||||||
});
|
});
|
||||||
|
|
||||||
req.setNoDelay(true);
|
req.setNoDelay(true);
|
||||||
|
|||||||
@@ -740,16 +740,9 @@ export const Sidebar = () => {
|
|||||||
<div
|
<div
|
||||||
className={`flex items-center gap-2 text-xs cursor-pointer transition-colors p-2 hover:bg-white/5 rounded-lg mx-2 group ${state.chatSettings.ollamaEnabled ? '' : 'opacity-60'
|
className={`flex items-center gap-2 text-xs cursor-pointer transition-colors p-2 hover:bg-white/5 rounded-lg mx-2 group ${state.chatSettings.ollamaEnabled ? '' : 'opacity-60'
|
||||||
}`}
|
}`}
|
||||||
onClick={async () => {
|
onClick={() => {
|
||||||
// Check Ollama status and open settings if not configured
|
// Always open AI Settings modal when clicked
|
||||||
const electron = (window as any).electron;
|
window.dispatchEvent(new CustomEvent('open-ai-settings'));
|
||||||
if (electron?.ollama) {
|
|
||||||
const status = await electron.ollama.getKeyStatus();
|
|
||||||
if (!status.hasKey) {
|
|
||||||
// Open AI Settings modal - dispatch a custom event
|
|
||||||
window.dispatchEvent(new CustomEvent('open-ai-settings'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
title={state.chatSettings.ollamaEnabled ? "Ollama Cloud connected" : "Click to configure Ollama Cloud"}
|
title={state.chatSettings.ollamaEnabled ? "Ollama Cloud connected" : "Click to configure Ollama Cloud"}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user