Tim Luka Horstmann commited on
Commit ·
602315d
1
Parent(s): 3fd3d0d
Better streaming
Browse files
app.py
CHANGED
|
@@ -220,6 +220,14 @@ async def stream_response(query, history, game_context=None, mode: Optional[str]
|
|
| 220 |
async for chunk in stream_response_local(query, history, game_context, mode):
|
| 221 |
yield chunk
|
| 222 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
def _format_game_context_for_prompt(game_context: Optional[Union[str, Dict[str, Any]]]) -> str:
|
| 224 |
"""Return a concise text snippet to inject into the system prompt from game context.
|
| 225 |
|
|
@@ -388,13 +396,13 @@ async def stream_response_gemini(query, history, game_context=None, mode: Option
|
|
| 388 |
if not first_token_logged:
|
| 389 |
logger.info(f"First token time (Gemini): {time.time() - start_time:.2f}s")
|
| 390 |
first_token_logged = True
|
| 391 |
-
yield
|
| 392 |
-
yield
|
| 393 |
|
| 394 |
except Exception as e:
|
| 395 |
logger.error(f"Gemini API error: {str(e)}")
|
| 396 |
-
yield f"
|
| 397 |
-
yield
|
| 398 |
|
| 399 |
|
| 400 |
async def stream_response_local(query, history, game_context=None, mode: Optional[str] = None):
|
|
@@ -441,8 +449,8 @@ async def stream_response_local(query, history, game_context=None, mode: Optiona
|
|
| 441 |
history_tokens = [len(generator.tokenize(msg["content"].encode('utf-8'), add_bos=False, special=True)) for msg in history]
|
| 442 |
except Exception as e:
|
| 443 |
logger.error(f"Tokenization error: {str(e)}")
|
| 444 |
-
yield f"
|
| 445 |
-
yield
|
| 446 |
return
|
| 447 |
|
| 448 |
total_tokens = system_tokens + query_tokens + sum(history_tokens) + len(history) * 10 + 10
|
|
@@ -470,12 +478,12 @@ async def stream_response_local(query, history, game_context=None, mode: Optiona
|
|
| 470 |
if not first_token_logged:
|
| 471 |
logger.info(f"First token time (local): {time.time() - start_time:.2f}s")
|
| 472 |
first_token_logged = True
|
| 473 |
-
yield
|
| 474 |
-
yield
|
| 475 |
except Exception as e:
|
| 476 |
logger.error(f"Generation error: {str(e)}")
|
| 477 |
-
yield f"
|
| 478 |
-
yield
|
| 479 |
|
| 480 |
class QueryRequest(BaseModel):
|
| 481 |
query: str
|
|
|
|
| 220 |
async for chunk in stream_response_local(query, history, game_context, mode):
|
| 221 |
yield chunk
|
| 222 |
|
| 223 |
+
def _text_event(text: str) -> str:
|
| 224 |
+
"""Encode model text as one SSE event without exposing framing characters."""
|
| 225 |
+
payload = json.dumps({"text": text}, ensure_ascii=False, separators=(",", ":"))
|
| 226 |
+
return f"data: {payload}\n\n"
|
| 227 |
+
|
| 228 |
+
def _done_event() -> str:
|
| 229 |
+
return 'data: {"done":true}\n\n'
|
| 230 |
+
|
| 231 |
def _format_game_context_for_prompt(game_context: Optional[Union[str, Dict[str, Any]]]) -> str:
|
| 232 |
"""Return a concise text snippet to inject into the system prompt from game context.
|
| 233 |
|
|
|
|
| 396 |
if not first_token_logged:
|
| 397 |
logger.info(f"First token time (Gemini): {time.time() - start_time:.2f}s")
|
| 398 |
first_token_logged = True
|
| 399 |
+
yield _text_event(chunk.text)
|
| 400 |
+
yield _done_event()
|
| 401 |
|
| 402 |
except Exception as e:
|
| 403 |
logger.error(f"Gemini API error: {str(e)}")
|
| 404 |
+
yield _text_event(f"Sorry, I encountered an error with Gemini API: {str(e)}")
|
| 405 |
+
yield _done_event()
|
| 406 |
|
| 407 |
|
| 408 |
async def stream_response_local(query, history, game_context=None, mode: Optional[str] = None):
|
|
|
|
| 449 |
history_tokens = [len(generator.tokenize(msg["content"].encode('utf-8'), add_bos=False, special=True)) for msg in history]
|
| 450 |
except Exception as e:
|
| 451 |
logger.error(f"Tokenization error: {str(e)}")
|
| 452 |
+
yield _text_event(f"Sorry, I encountered a tokenization error: {str(e)}")
|
| 453 |
+
yield _done_event()
|
| 454 |
return
|
| 455 |
|
| 456 |
total_tokens = system_tokens + query_tokens + sum(history_tokens) + len(history) * 10 + 10
|
|
|
|
| 478 |
if not first_token_logged:
|
| 479 |
logger.info(f"First token time (local): {time.time() - start_time:.2f}s")
|
| 480 |
first_token_logged = True
|
| 481 |
+
yield _text_event(token)
|
| 482 |
+
yield _done_event()
|
| 483 |
except Exception as e:
|
| 484 |
logger.error(f"Generation error: {str(e)}")
|
| 485 |
+
yield _text_event(f"Sorry, I encountered an error during generation: {str(e)}")
|
| 486 |
+
yield _done_event()
|
| 487 |
|
| 488 |
class QueryRequest(BaseModel):
|
| 489 |
query: str
|