Spaces:
Runtime error
Runtime error
| from __future__ import annotations | |
| import asyncio | |
| from typing import AsyncIterator | |
| import httpx | |
| import typer | |
| from colorama import Fore, Style, init | |
| API_URL = "http://localhost:8000" | |
| app = typer.Typer(add_completion=False, help="Interact with the LLM backend API") | |
| async def _get_sessions(user: str, server: str) -> list[str]: | |
| async with httpx.AsyncClient(base_url=server) as client: | |
| resp = await client.get(f"/sessions/{user}") | |
| resp.raise_for_status() | |
| data = resp.json() | |
| return data.get("sessions", []) | |
| async def _stream_chat( | |
| user: str, session: str, prompt: str, server: str | |
| ) -> AsyncIterator[str]: | |
| async with httpx.AsyncClient(base_url=server, timeout=None) as client: | |
| async with client.stream( | |
| "POST", | |
| "/chat/stream", | |
| json={"user": user, "session": session, "prompt": prompt}, | |
| ) as resp: | |
| resp.raise_for_status() | |
| async for line in resp.aiter_lines(): | |
| if line: | |
| yield line | |
| async def _chat_loop(user: str, server: str) -> None: | |
| init(autoreset=True) | |
| sessions = await _get_sessions(user, server) | |
| session = "default" | |
| if sessions: | |
| typer.echo("Existing sessions:") | |
| for idx, name in enumerate(sessions, 1): | |
| typer.echo(f" {idx}. {name}") | |
| choice = typer.prompt( | |
| "Select session number or enter new name", default=str(len(sessions)) | |
| ) | |
| if choice.isdigit() and 1 <= int(choice) <= len(sessions): | |
| session = sessions[int(choice) - 1] | |
| else: | |
| session = choice.strip() or session | |
| else: | |
| session = typer.prompt("Session name", default=session) | |
| typer.echo( | |
| f"Chatting as {Fore.GREEN}{user}{Style.RESET_ALL} in session '{session}'" | |
| ) | |
| while True: | |
| try: | |
| msg = typer.prompt(f"{Fore.CYAN}You{Style.RESET_ALL}") | |
| except EOFError: | |
| break | |
| if msg.strip().lower() in {"exit", "quit"}: | |
| break | |
| async for part in _stream_chat(user, session, msg, server): | |
| typer.echo(f"{Fore.YELLOW}{part}{Style.RESET_ALL}") | |
| def main( | |
| user: str = typer.Option("default", "--user", "-u"), | |
| server: str = typer.Option(API_URL, "--server", "-s"), | |
| ) -> None: | |
| """Start an interactive chat session.""" | |
| asyncio.run(_chat_loop(user, server)) | |
| if __name__ == "__main__": # pragma: no cover - manual execution | |
| app() | |