a9 commited on
Commit
40a4ea0
·
verified ·
1 Parent(s): af08a0e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -439
app.py CHANGED
@@ -1,468 +1,102 @@
1
  from fastapi import FastAPI, Response, Cookie
2
- from fastapi.responses import HTMLResponse
3
  from pydantic import BaseModel, Field
4
- import time
5
- import os
 
6
 
7
- value = os.environ.get('YOUR_ENV_KEY')
8
 
9
  app = FastAPI()
10
 
11
- Tokens = []
12
- History = []
13
-
14
- @app.get("/", response_class=HTMLResponse)
15
- async def read_root(response: Response):
16
- token = time.time()
17
- Tokens.append(str(token))
18
- History.append([{"role": "system", "content": "You are the Prompt Optimization Engine (POE), a tool designed to maximize the clarity and effectiveness of user queries for large language models. Your sole function is to accept a user-submitted prompt, analyze its core intent, context, and desired output format. You must then return a single, improved, streamlined version. The refined prompt must be concise, articulate the required persona and constraints clearly, and fully preserve the original user intent. Always prioritize action-oriented language and remove any conversational filler or ambiguity."}])
19
- response.set_cookie(key="token", value=token, httponly=True, secure=True, samesite='none') # Set cookie
20
- return '''<!DOCTYPE html>
21
- <html lang="en">
22
- <head>
23
- <meta charset="UTF-8">
24
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
25
- <title>Chatbot Assistant</title>
26
- <script src="https://cdn.tailwindcss.com"></script>
27
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
28
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
29
- <style>
30
- body {
31
- font-family: 'Inter', sans-serif;
32
- background-color: #1a202c; /* Dark background for the body */
33
- display: flex;
34
- justify-content: center;
35
- align-items: center;
36
- min-height: 100vh;
37
- margin: 0;
38
- padding: 16px;
39
- box-sizing: border-box;
40
- color: #e2e8f0; /* Light text color for general body text */
41
- }
42
- code {
43
- margin: 6px 0px;
44
- display: block;
45
- border-radius: 12px;
46
- overflow-x: scroll;
47
- background-color: #1e1e1e;
48
- padding: 12px;
49
- scrollbar-width: none;
50
- }
51
- .chat-container {
52
- display: flex;
53
- flex-direction: column;
54
- width: 100%;
55
- max-width: 800px;
56
- height: 90vh;
57
- background-color: #2d3748; /* Darker background for chat box */
58
- border-radius: 1.5rem;
59
- box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3); /* More pronounced shadow for dark mode */
60
- overflow: hidden;
61
- border: 1px solid #4a5568; /* Subtle border for dark mode */
62
- }
63
- .chat-header {
64
- background: linear-gradient(to right, #6a0076, #12327a); /* Darker blue gradient header */
65
- color: #ffffff;
66
- padding: 1.5rem;
67
- text-align: center;
68
- font-size: 1.75rem;
69
- font-weight: 700;
70
- border-top-left-radius: 1.5rem;
71
- border-top-right-radius: 1.5rem;
72
- }
73
- .chat-messages {
74
- flex-grow: 1;
75
- padding: 1.5rem;
76
- overflow-y: auto;
77
- -webkit-overflow-scrolling: touch;
78
- display: flex;
79
- flex-direction: column;
80
- gap: 1rem;
81
- }
82
- .message {
83
- max-width: 75%;
84
- padding: 0.85rem 1.25rem;
85
- border-radius: 1.25rem;
86
- word-wrap: break-word;
87
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* Subtle shadow for messages */
88
- animation: fadeIn 0.3s ease-out;
89
- }
90
- .user-message {
91
- background-color: #12327a; /* Blue for user messages in dark mode */
92
- align-self: flex-end;
93
- color: #ffffff; /* White text for user messages */
94
- border-bottom-right-radius: 0.5rem;
95
- }
96
- .assistant-message {
97
- background-color: #4a5568; /* Darker gray for assistant messages */
98
- align-self: flex-start;
99
- color: #e2e8f0; /* Light text for assistant messages */
100
- border-bottom-left-radius: 0.5rem;
101
- }
102
- .input-area {
103
- display: flex;
104
- align-items: center;
105
- padding: 1.5rem;
106
- border-top: 1px solid #4a5568; /* Darker border at the top */
107
- background-color: #2d3748; /* Match chat box background */
108
- gap: 1rem;
109
- }
110
- .input-area textarea {
111
- flex-grow: 1;
112
- padding: 0.85rem 1.25rem;
113
- border: 2px solid #718096; /* Lighter border for contrast */
114
- border-radius: 1.25rem;
115
- resize: none;
116
- outline: none;
117
- font-size: 1rem;
118
- line-height: 1.5;
119
- min-height: 48px;
120
- max-height: 150px;
121
- overflow-y: auto;
122
- transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
123
- background-color: #2d3748; /* Dark background for textarea */
124
- color: #e2e8f0; /* Light text color for textarea */
125
- }
126
- .input-area textarea:focus {
127
- border-color: #63b3ed; /* Lighter blue border on focus */
128
- box-shadow: 0 0 0 3px rgba(99, 179, 237, 0.2); /* Lighter blue shadow on focus */
129
- }
130
- .input-area button {
131
- background: linear-gradient(to right, #4299e1, #3182ce); /* Blue gradient button */
132
- color: #ffffff;
133
- padding: 0.85rem 1.75rem;
134
- border-radius: 1.25rem;
135
- font-weight: 600;
136
- cursor: pointer;
137
- transition: all 0.2s ease-in-out;
138
- display: flex;
139
- align-items: center;
140
- justify-content: center;
141
- gap: 0.5rem;
142
- box-shadow: 0 4px 10px rgba(66, 153, 225, 0.3);
143
- transform: translateY(0);
144
- }
145
- .input-area button:hover {
146
- background: linear-gradient(to right, #3182ce, #2b6cb0);
147
- box-shadow: 0 6px 15px rgba(66, 153, 225, 0.4);
148
- transform: translateY(-2px);
149
- }
150
- .input-area button:disabled {
151
- background: #4a5568; /* Dark gray when disabled */
152
- cursor: not-allowed;
153
- box-shadow: none;
154
- transform: translateY(0);
155
- }
156
- /* Summarize button specific styles for dark mode */
157
- #summarize-button {
158
- background: linear-gradient(to right, #805ad5, #6b46c1); /* Darker purple gradient */
159
- box-shadow: 0 4px 10px rgba(128, 90, 213, 0.3);
160
- }
161
- #summarize-button:hover {
162
- background: linear-gradient(to right, #6b46c1, #553c9a);
163
- box-shadow: 0 6px 15px rgba(128, 90, 213, 0.4);
164
- }
165
-
166
- .loading-indicator {
167
- display: flex;
168
- align-items: center;
169
- gap: 0.5rem;
170
- font-style: italic;
171
- color: #a0aec0; /* Lighter gray for loading text */
172
- align-self: flex-start;
173
- animation: fadeIn 0.3s ease-out;
174
- }
175
- .loading-dot {
176
- width: 8px;
177
- height: 8px;
178
- background-color: #a0aec0; /* Lighter gray for dots */
179
- border-radius: 50%;
180
- animation: bounce 1.4s infinite ease-in-out both;
181
- }
182
- .loading-dot:nth-child(1) { animation-delay: -0.32s; }
183
- .loading-dot:nth-child(2) { animation-delay: -0.16s; }
184
- .loading-dot:nth-child(3) { animation-delay: 0s; }
185
- .space {
186
- height: 4px;
187
- }
188
-
189
- @layer base {
190
- p {
191
- margin: 6px 0px;
192
- }
193
- menu, ol, ul {
194
- list-style: inside;
195
- margin: 0px;
196
- padding: 4px;
197
- }
198
- }
199
-
200
- code::-webkit-scrollbar {
201
- display: none; /* Chrome, Safari */
202
- }
203
- .status-token {
204
- text-align: right;
205
- font-size: x-small;
206
- margin-top: 4px;
207
- }
208
- @keyframes bounce {
209
- 0%, 80%, 100% { transform: scale(0); }
210
- 40% { transform: scale(1); }
211
- }
212
- @keyframes fadeIn {
213
- from { opacity: 0; transform: translateY(10px); }
214
- to { opacity: 1; transform: translateY(0); }
215
- }
216
-
217
- /* Responsive adjustments (same as before, unaffected by dark mode colors) */
218
- @media (max-width: 768px) {
219
- body {
220
- padding: 0;
221
- }
222
- .chat-container {
223
- height: 100vh;
224
- border-radius: 0;
225
- box-shadow: none;
226
- border: none;
227
- }
228
- .chat-header {
229
- border-radius: 0;
230
- font-size: 1.5rem;
231
- padding: 1rem;
232
- }
233
- .chat-messages {
234
- padding: 0.75rem;
235
- gap: 0.7rem;
236
- }
237
- .message {
238
- max-width: 100%;
239
- padding: 0.5rem 0.75rem;
240
- border-radius: 0.75rem;
241
- }
242
- .input-area {
243
- flex-direction: column;
244
- padding: 1rem;
245
- gap: 0.75rem;
246
- }
247
- .input-area textarea {
248
- width: 100%;
249
- min-height: 40px;
250
- padding: 0.5rem 0.75rem;
251
- border-radius: 0.75rem;
252
- }
253
- .input-area button {
254
- width: 100%;
255
- padding: 0.5rem 0.75rem;
256
- border-radius: 0.75rem;
257
- }
258
- }
259
- </style>
260
- </head>
261
- <body class="antialiased">
262
- <div class="chat-container">
263
- <div class="chat-header">
264
- Chat Assistant
265
- </div>
266
-
267
- <div id="chat-messages" class="chat-messages">
268
- <div class="message assistant-message">
269
- <p style="font-style: italic;">This AI model provides information based on pre-existing data and patterns, but may not always offer accurate, up-to-date, or context-specific advice. Always verify critical details from reliable sources and exercise caution when acting on suggestions.</p>
270
- </div>
271
- </div>
272
-
273
- <div class="input-area">
274
- <textarea
275
- id="user-input"
276
- placeholder="Type your message..."
277
- rows="1"
278
- class="shadow-sm block w-full"
279
- ></textarea>
280
- <button id="send-button">
281
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
282
- <path d="M10.894 2.553a1 1 0 00-1.788 0l-7 14a1 1 0 001.169 1.409l5-1.429A1 1 0 009 15.571V11a1 1 0 112 0v4.571a1 1 0 00.553.894l5 1.429a1 1 0 001.169-1.409l-7-14z" />
283
- </svg>
284
- Send
285
- </button>
286
- <button id="summarize-button" style="display:none;">
287
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
288
- <path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0113 3.414L16.586 7A2 2 0 0117 8.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1-3a1 1 0 000 2h.01a1 1 0 000-2H7zm0 6a1 1 0 000 2h.01a1 1 0 000-2H7zm3-6a1 1 0 000 2h3a1 1 0 100-2h-3zm0 6a1 1 0 000 2h3a1 1 0 100-2h-3z" clip-rule="evenodd" />
289
- </svg>
290
- Summarize Chat
291
- </button>
292
- </div>
293
- </div>
294
-
295
- <script>
296
- const DOM = {
297
- chatMessages: document.getElementById('chat-messages'),
298
- userInput: document.getElementById('user-input'),
299
- sendButton: document.getElementById('send-button'),
300
- summarizeButton: document.getElementById('summarize-button'),
301
- };
302
-
303
- const chatHistory = [];
304
-
305
- /**
306
- * Adds a message to the chat display and updates chat history.
307
- * @param {string} text - The message content.
308
- * @param {'user'|'assistant'|'initial-assistant'} sender - The sender of the message.
309
- */
310
- function addMessage(text, sender, time, t_per_s) {
311
- const messageDiv = document.createElement('div');
312
- messageDiv.classList.add('message', sender === 'user' ? 'user-message' : 'assistant-message');
313
- const parsedHTML = marked.parse(text);
314
- const spacedHTML = parsedHTML.replace(/<\/p>\\n<p>/g, '</p><p class="space"></p><p>');
315
- if (sender == 'user') {
316
- messageDiv.innerHTML = parsedHTML;
317
- } else {
318
- messageDiv.innerHTML = parsedHTML + `<p class="status-token">${time} sec &nbsp; ${t_per_s} T/s</p>`;
319
- }
320
- DOM.chatMessages.appendChild(messageDiv);
321
- DOM.chatMessages.scrollTop = DOM.chatMessages.scrollHeight;
322
-
323
- if (sender !== 'initial-assistant') {
324
- chatHistory.push({ role: sender, parts: [{ text: text }] });
325
- }
326
- }
327
-
328
- /** Shows a loading indicator in the chat. */
329
- function showLoadingIndicator() {
330
- const loadingDiv = document.createElement('div');
331
- loadingDiv.id = 'loading-indicator';
332
- loadingDiv.classList.add('loading-indicator');
333
- loadingDiv.innerHTML = `
334
- <span>Assistant is typing</span>
335
- <div class="loading-dot"></div>
336
- <div class="loading-dot"></div>
337
- <div class="loading-dot"></div>
338
- `;
339
- DOM.chatMessages.appendChild(loadingDiv);
340
- DOM.chatMessages.scrollTop = DOM.chatMessages.scrollHeight;
341
- }
342
-
343
- /** Removes the loading indicator from the chat. */
344
- function removeLoadingIndicator() {
345
- document.getElementById('loading-indicator')?.remove();
346
- }
347
 
348
- /** Sets the disabled state of input and buttons. */
349
- function setControlsDisabled(disabled) {
350
- DOM.sendButton.disabled = disabled;
351
- DOM.summarizeButton.disabled = disabled;
352
- DOM.userInput.disabled = disabled;
353
- }
354
-
355
- /** Sends a user message to the backend API. */
356
- async function sendMessage() {
357
- const message = DOM.userInput.value.trim();
358
- if (!message) return;
359
-
360
- addMessage(message, 'user');
361
- DOM.userInput.value = '';
362
- setControlsDisabled(true);
363
- showLoadingIndicator();
364
-
365
- try {
366
- const response = await fetch(`/response`, {
367
- method: 'POST',
368
- headers: { 'Content-Type': 'application/json' },
369
- body: JSON.stringify({ prompt: message }),
370
- });
371
-
372
- if (!response.ok) {
373
- throw new Error(`HTTP error! status: ${response.status}`);
374
- }
375
 
376
- const data = await response.json();
377
- addMessage(data.text || "Sorry, I couldn't get a response.", 'assistant', data.time, data.t_per_sec);
378
- } catch (error) {
379
- console.error('Error sending message:', error);
380
- addMessage('Error: Could not connect to the assistant. Please try again.', 'assistant');
381
- } finally {
382
- removeLoadingIndicator();
383
- setControlsDisabled(false);
384
- DOM.userInput.focus();
385
- adjustTextareaHeight();
386
- }
387
- }
388
 
389
- /** Dynamically adjusts the textarea height. */
390
- function adjustTextareaHeight() {
391
- DOM.userInput.style.height = 'auto';
392
- DOM.userInput.style.height = (DOM.userInput.scrollHeight) + 'px';
393
- }
394
 
395
- // Event Listeners
396
- DOM.sendButton.addEventListener('click', sendMessage);
397
- // DOM.summarizeButton.addEventListener('click', summarizeChat);
 
 
 
 
398
 
399
- DOM.userInput.addEventListener('keypress', (event) => {
400
- if (event.key === 'Enter' && !event.shiftKey) {
401
- event.preventDefault();
402
- sendMessage();
403
- }
404
- });
405
 
406
- DOM.userInput.addEventListener('input', adjustTextareaHeight);
 
 
407
 
408
- // Initial setup
409
- document.addEventListener('DOMContentLoaded', () => {
410
- // addMessage('Hello! How can I assist you today?', 'initial-assistant');
411
- DOM.userInput.focus();
412
- adjustTextareaHeight(); // Set initial height for empty textarea
413
- });
414
- </script>
415
- </body>
416
- </html>'''
 
 
 
 
 
 
 
 
 
417
 
 
418
 
419
- from google import genai
420
- from google.genai import types
421
- import requests
422
 
 
 
 
423
 
424
- Api_key = os.getenv('API_KEY')
425
- System_instruction = '''**System Prompt for a Programmer-Oriented Coding Assistant:**\n\n> You are a highly focused, fast, and expert-level coding assistant built for professional programmers.\n> Your primary role is **to assist with code writing, debugging, refactoring, optimization, and architecture**.\n> Avoid unnecessary explanations unless asked. Do not teach—**support the user like a senior pair programmer** who assumes context and skill. Prioritize clean, correct, and efficient code.\n\n> Always:\n> * Get straight to the point.\n> * Suggest the most practical and scalable solution.\n> * Respond with complete code blocks when needed.\n> * Use strong defaults and modern conventions.\n> * Assume the user knows what they're doing.\n> * Think ahead: anticipate potential pitfalls or better approaches.\n> * Give fast, minimal answers when asked for quick help.\n\n> Only elaborate if specifically requested (e.g., “explain,” “why,” “teach,” “verbose”)'''
426
 
427
 
428
- client = genai.Client(api_key=Api_key)
 
 
429
 
430
- class ChatRequest(BaseModel):
431
- """Request model for the chat endpoint."""
432
- prompt: str
433
 
434
- def gen(prompt):
435
- response = client.models.generate_content(
436
- model="gemma-3-4b-it",
437
- contents= prompt
438
- )
439
- return response.text
440
 
441
  @app.post("/response")
442
- async def handle_chat(chat_request: ChatRequest, token: str = Cookie(None)):
443
  a= time.time()
444
- if token in Tokens:
445
- i = Tokens.index(token)
446
- History[i].append({"role": "user", "content": chat_request.prompt})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
 
448
- text = '<start_of_turn>system\n'+System_instruction+'<end_of_turn>\n<start_of_turn>user\n'
449
- for j in History[i]:
450
- if j['role']== 'user':
451
- text = text + j['content'] + '<end_of_turn>\n<start_of_turn>model\n'
452
- else : text = text + j['content'] + '<end_of_turn>\n<start_of_turn>user\n'
453
- stream = gen(text)
454
- History[i].append({"role": "assistant", "content": stream})
455
- b = time.time()
456
- return {"text": stream,
457
- "time": (b-a)/1000,
458
- "t_per_sec": 0}
459
- else: return 'Please stop. Just refresh the page.'
460
 
461
- @app.post("/history")
462
- async def history(chat_request: ChatRequest):
463
- if chat_request.prompt == value:
464
- time.sleep(10)
465
- return History
466
 
467
  if __name__ == "__main__":
468
  import uvicorn
 
1
  from fastapi import FastAPI, Response, Cookie
 
2
  from pydantic import BaseModel, Field
3
+ import time, os, base64, uuid, requests
4
+ from google import genai
5
+ from google.genai import types
6
 
 
7
 
8
  app = FastAPI()
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ Tokens = []
12
+ user = [[user, conv ids]]
13
+ # In-memory storage (Better to use a Dict)
14
+ sessions = {} # Format: {token: {conv_id: [history_list]}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ class ChatRequest(BaseModel):
17
+ prompt: str
18
+ conv_id: str
 
 
 
 
 
 
 
 
 
19
 
20
+ class NewConv(BaseModel):
21
+ prompt: str
 
 
 
22
 
23
+ def gen(prompt):
24
+ try:
25
+ response = client.models.generate_content(model="gemma-3-4b-it", contents=prompt)
26
+ return response.text
27
+ except Exception as e:
28
+ print(f"API Error: {e}")
29
+ return None
30
 
31
+ def getSystemPrompt():
32
+ return text #TODO: System Prompt builder
 
 
 
 
33
 
34
+ def getConvId():
35
+ u = uuid.uuid4().bytes[:12]
36
+ return base64.urlsafe_b64encode(u).rstrip(b'=').decode()
37
 
38
+ @app.post("/new_conversation")
39
+ async def handleNewConv(new_conv: NewConv, token: str = Cookie(None)):
40
+ a = time.time()
41
+ user_convs = sessions.get(token)
42
+ if not user_convs:
43
+ return "Error" # TODO: Error implementation
44
+ history = [
45
+ types.Content(role='model', parts=[types.Part(text=getSystemPrompt())]),
46
+ types.Content(role='user', parts=[types.Part(text=new_conv.prompt)])
47
+ ]
48
+ text = gen(history)
49
+ if text:
50
+ conv_id = getConvId()
51
+ raw_history = [["model", getSystemPrompt()]]
52
+ raw_history.append(["user", new_conv.prompt])
53
+ raw_history.append(["model", text])
54
+ user_convs[conv_id] = raw_history
55
+ return text
56
 
57
+ return None # TODO: Error implementation
58
 
 
 
 
59
 
60
+ @app.post("/new_conv")
61
+ async def handleNewConv(new_conv: NewConv):
62
+ a = time.time()
63
 
64
+ return {text: str(a), conv_id: getConvId()} # TODO: Error implementation
 
65
 
66
 
67
+ @app.post("/gen_resp")
68
+ async def handleNewConv(new_conv: NewConv):
69
+ a = time.time()
70
 
71
+ return {text: str(a)} # TODO: Error implementation
 
 
72
 
 
 
 
 
 
 
73
 
74
  @app.post("/response")
75
+ async def handleChat(chat_request: ChatRequest, token: str = Cookie(None)):
76
  a= time.time()
77
+ conv_id = chat_request.conv_id
78
+ # Check if token and conversation exist
79
+ user_convs = sessions.get(token)
80
+ if not user_convs or conv_id not in user_convs:
81
+ return "Please stop. Just refresh the page." # TODO: Error implementation
82
+ # Prepare history
83
+ raw_history = user_convs[conv_id]
84
+ history = [
85
+ types.Content(role=k[0], parts=[types.Part(text=k[1])])
86
+ for k in raw_history
87
+ ]
88
+ history.append(types.Content(role='user', parts=[types.Part(text=chat_request.prompt)]))
89
+ # Generate response
90
+ text = gen(history)
91
+ if text:
92
+ raw_history.append(["user", chat_request.prompt])
93
+ raw_history.append(["model", text])
94
+ # Optional: Update history with new response here
95
+ return text
96
+
97
+ return None # TODO: Error implementation
98
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
 
 
 
 
 
100
 
101
  if __name__ == "__main__":
102
  import uvicorn