// src/components/StreamingChatTest.jsx
// Simple component to test streaming chat functionality
import React, { useState } from 'react';
import { useMCP } from '../hooks/useMCP';
const StreamingChatTest = () => {
const { isConnected, chatStream, availableModels, error } = useMCP();
const [message, setMessage] = useState('');
const [selectedModel, setSelectedModel] = useState('mistral:latest');
const [streamingResponse, setStreamingResponse] = useState('');
const [isStreaming, setIsStreaming] = useState(false);
const [fullResponse, setFullResponse] = useState('');
const handleStreamingChat = async () => {
if (!message.trim()) return;
setIsStreaming(true);
setStreamingResponse('');
setFullResponse('');
try {
const response = await chatStream(
message,
selectedModel,
{},
(chunk, data) => {
// This callback is called for each chunk received
setStreamingResponse(prev => prev + chunk);
}
);
// Final response when streaming is complete
setFullResponse(response.response);
console.log('Streaming completed:', response);
} catch (err) {
console.error('Streaming chat error:', err);
} finally {
setIsStreaming(false);
}
};
const ollamaModels = availableModels.ollama || [];
if (!isConnected) {
return (
<div style={{ padding: '20px', backgroundColor: '#f8d7da', borderRadius: '4px' }}>
<h3>MCP Server Not Connected</h3>
<p>Connect to the server to test streaming chat</p>
</div>
);
}
return (
<div style={{ padding: '20px', maxWidth: '800px', margin: '0 auto' }}>
<h2>🚀 Streaming Chat Test</h2>
{error && (
<div style={{
padding: '10px',
backgroundColor: '#f8d7da',
borderRadius: '4px',
marginBottom: '20px',
color: '#721c24'
}}>
Error: {error}
</div>
)}
{/* Model Selection */}
<div style={{ marginBottom: '15px' }}>
<label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>
Select Model:
</label>
<select
value={selectedModel}
onChange={(e) => setSelectedModel(e.target.value)}
style={{
padding: '8px',
borderRadius: '4px',
border: '1px solid #ddd',
minWidth: '200px'
}}
>
{ollamaModels.map(model => (
<option key={model} value={model}>{model}</option>
))}
</select>
</div>
{/* Message Input */}
<div style={{ marginBottom: '15px' }}>
<label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>
Your Message:
</label>
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Type your message here..."
rows={3}
style={{
width: '100%',
padding: '10px',
borderRadius: '4px',
border: '1px solid #ddd',
resize: 'vertical'
}}
/>
</div>
{/* Send Button */}
<button
onClick={handleStreamingChat}
disabled={isStreaming || !message.trim()}
style={{
padding: '10px 20px',
backgroundColor: isStreaming ? '#6c757d' : '#007bff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: isStreaming ? 'not-allowed' : 'pointer',
fontSize: '16px',
marginBottom: '20px'
}}
>
{isStreaming ? '⏳ Streaming...' : '📡 Send Streaming Message'}
</button>
{/* Streaming Response Display */}
{(streamingResponse || isStreaming) && (
<div style={{ marginBottom: '20px' }}>
<h3>
🌊 Live Streaming Response
{isStreaming && (
<span style={{
display: 'inline-block',
marginLeft: '10px',
animation: 'blink 1s infinite',
color: '#007bff'
}}>
●
</span>
)}
</h3>
<div style={{
padding: '15px',
backgroundColor: '#f8f9fa',
border: '2px solid #007bff',
borderRadius: '4px',
minHeight: '100px',
whiteSpace: 'pre-wrap',
fontFamily: 'system-ui, -apple-system, sans-serif',
lineHeight: '1.5'
}}>
{streamingResponse || 'Waiting for response...'}
</div>
</div>
)}
{/* Final Response */}
{fullResponse && !isStreaming && (
<div>
<h3>✅ Final Response</h3>
<div style={{
padding: '15px',
backgroundColor: '#d4edda',
border: '1px solid #c3e6cb',
borderRadius: '4px',
whiteSpace: 'pre-wrap',
fontFamily: 'system-ui, -apple-system, sans-serif',
lineHeight: '1.5'
}}>
{fullResponse}
</div>
</div>
)}
{/* Usage Info */}
<div style={{
marginTop: '30px',
padding: '15px',
backgroundColor: '#e9ecef',
borderRadius: '4px',
fontSize: '14px'
}}>
<h4>How Streaming Works:</h4>
<ul style={{ margin: '10px 0', paddingLeft: '20px' }}>
<li>Type a message and select a model</li>
<li>Click "Send Streaming Message"</li>
<li>Watch the response appear in real-time as it's generated</li>
<li>The blue dot (●) shows when streaming is active</li>
<li>Final response is displayed when streaming completes</li>
</ul>
</div>
<style jsx>{`
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
`}</style>
</div>
);
};
export default StreamingChatTest;