Spaces:
Sleeping
Sleeping
File size: 6,167 Bytes
4ce4f5d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# app.py
from flask import Flask, request, jsonify, render_template_string
from llama_cpp import Llama
from pydantic import BaseModel, ValidationError
from typing import List
import logging
app = Flask(__name__)
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Initialize the Llama model
llm = Llama.from_pretrained(
repo_id="bartowski/Marco-o1-GGUF",
filename="Marco-o1-Q3_K_M.gguf",
)
# Pydantic Models
class Message(BaseModel):
role: str
content: str
class ChatRequest(BaseModel):
messages: List[Message]
class ChatResponse(BaseModel):
response: str
# Route to serve the chat interface
@app.route('/')
def index():
html_content = """
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Llama Chat Interface</title>
<style>
body { font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px; }
#chat-container { max-width: 600px; margin: auto; background: #fff; padding: 20px; border-radius: 5px; }
#messages { border: 1px solid #ccc; padding: 10px; height: 300px; overflow-y: scroll; }
.message { margin-bottom: 15px; }
.user { color: blue; }
.assistant { color: green; }
#input-form { display: flex; margin-top: 10px; }
#input-form input { flex: 1; padding: 10px; border: 1px solid #ccc; border-radius: 3px; }
#input-form button { padding: 10px; border: none; background: #28a745; color: #fff; cursor: pointer; border-radius: 3px; margin-left: 5px; }
#input-form button:hover { background: #218838; }
</style>
</head>
<body>
<div id="chat-container">
<h2>Llama Chatbot</h2>
<div id="messages"></div>
<form id="input-form">
<input type="text" id="user-input" placeholder="Type your message here..." required />
<button type="submit">Send</button>
</form>
</div>
<!-- Babel CDN -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- Your JavaScript Code -->
<script type="text/babel">
const chatContainer = document.getElementById('messages');
const inputForm = document.getElementById('input-form');
const userInput = document.getElementById('user-input');
// Function to append messages to the chat container
function appendMessage(role, content) {
const messageDiv = document.createElement('div');
messageDiv.classList.add('message');
if (role === 'user') {
messageDiv.classList.add('user');
messageDiv.innerHTML = '<strong>You:</strong> ' + content;
} else if (role === 'assistant') {
messageDiv.classList.add('assistant');
messageDiv.innerHTML = '<strong>Assistant:</strong> ' + content;
}
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
// Handle form submission
inputForm.addEventListener('submit', async (e) => {
e.preventDefault();
const message = userInput.value.trim();
if (message === '') return;
appendMessage('user', message);
userInput.value = '';
try {
const response = await fetch('/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
messages: [
{
role: 'user',
content: message
}
]
})
});
if (!response.ok) {
const errorData = await response.json();
appendMessage('assistant', 'Error: ' + (errorData.error || 'Unknown error'));
return;
}
const data = await response.json();
appendMessage('assistant', data.response);
} catch (error) {
appendMessage('assistant', 'Error: ' + error.message);
}
});
</script>
</body>
</html>
"""
return render_template_string(html_content)
# Chat API Endpoint
@app.route('/chat', methods=['POST'])
def chat():
try:
# Parse and validate the JSON request using Pydantic
json_data = request.get_json()
if not json_data:
logger.warning("Invalid JSON payload received.")
return jsonify({'error': 'Invalid JSON payload'}), 400
chat_request = ChatRequest(**json_data)
logger.info(f"Received messages: {chat_request.messages}")
# Convert Pydantic models to the format expected by Llama
messages = [message.dict() for message in chat_request.messages]
# Generate the chat completion
completion = llm.create_chat_completion(messages=messages)
logger.info(f"Generated completion: {completion}")
# Create the response using Pydantic
chat_response = ChatResponse(response=completion)
return jsonify(chat_response.dict())
except ValidationError as ve:
# Handle validation errors from Pydantic
logger.error(f"Pydantic validation error: {ve.errors()}")
errors = [{"field": error['loc'][0], "message": error['msg']} for error in ve.errors()]
return jsonify({'error': errors}), 422
except Exception as e:
# Handle unexpected errors
logger.error(f"Unexpected error: {str(e)}")
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)
|