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() | |