e4dcfc49aa
Tests / Lint and Format (push) Waiting to run
Tests / Web Node Tests (push) Waiting to run
Tests / Import Check (Python 3.11) (push) Waiting to run
Tests / Import Check (Python 3.12) (push) Waiting to run
Tests / Import Check (Python 3.13) (push) Waiting to run
Tests / Import Check (Python 3.14) (push) Waiting to run
Tests / Python Tests (Python 3.11) (push) Blocked by required conditions
Tests / Python Tests (Python 3.12) (push) Blocked by required conditions
Tests / Python Tests (Python 3.13) (push) Blocked by required conditions
Tests / Python Tests (Python 3.14) (push) Blocked by required conditions
Tests / Test Summary (push) Blocked by required conditions
102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
"""CLI commands for shared session management."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
import typer
|
|
|
|
from deeptutor.app import DeepTutorApp
|
|
|
|
from .chat import ChatState, _chat_repl
|
|
from .common import console, maybe_run, print_session_table
|
|
|
|
|
|
def register(app: typer.Typer) -> None:
|
|
@app.command("list")
|
|
def list_sessions(
|
|
limit: int = typer.Option(20, "--limit", help="Maximum sessions to show."),
|
|
) -> None:
|
|
"""List existing sessions."""
|
|
maybe_run(_list_sessions(limit))
|
|
|
|
@app.command("show")
|
|
def show_session(
|
|
session_id: str = typer.Argument(..., help="Session id."),
|
|
fmt: str = typer.Option("rich", "--format", help="Output format: rich | json."),
|
|
) -> None:
|
|
"""Show a session and its persisted messages."""
|
|
maybe_run(_show_session(session_id, fmt))
|
|
|
|
@app.command("open")
|
|
def open_session(
|
|
session_id: str = typer.Argument(..., help="Session id."),
|
|
) -> None:
|
|
"""Enter the interactive chat REPL with an existing session."""
|
|
maybe_run(_chat_repl(ChatState(session_id=session_id)))
|
|
|
|
@app.command("delete")
|
|
def delete_session(
|
|
session_id: str = typer.Argument(..., help="Session id."),
|
|
) -> None:
|
|
"""Delete a session and all of its turns/messages."""
|
|
maybe_run(_delete_session(session_id))
|
|
|
|
@app.command("rename")
|
|
def rename_session(
|
|
session_id: str = typer.Argument(..., help="Session id."),
|
|
title: str = typer.Option(..., "--title", help="New session title."),
|
|
) -> None:
|
|
"""Rename a session."""
|
|
maybe_run(_rename_session(session_id, title))
|
|
|
|
|
|
async def _list_sessions(limit: int) -> None:
|
|
client = DeepTutorApp()
|
|
sessions = await client.list_sessions(limit=limit)
|
|
print_session_table(sessions)
|
|
|
|
|
|
async def _show_session(session_id: str, fmt: str) -> None:
|
|
client = DeepTutorApp()
|
|
session = await client.get_session(session_id)
|
|
if session is None:
|
|
console.print(f"[red]Session not found:[/] {session_id}")
|
|
raise typer.Exit(code=1)
|
|
|
|
if fmt == "json":
|
|
console.print(json.dumps(session, ensure_ascii=False, indent=2, default=str))
|
|
return
|
|
|
|
console.print(f"[bold]{session.get('title', '')}[/] ({session.get('id', '')})")
|
|
console.print(
|
|
f"[dim]capability={session.get('capability', '') or 'chat'} "
|
|
f"status={session.get('status', '')} "
|
|
f"messages={len(session.get('messages', []))}[/]",
|
|
highlight=False,
|
|
)
|
|
for message in session.get("messages", []):
|
|
role = str(message.get("role", "")).upper()
|
|
content = str(message.get("content", "") or "").strip()
|
|
console.print(f"\n[cyan]{role}[/]")
|
|
if content:
|
|
console.print(content)
|
|
|
|
|
|
async def _delete_session(session_id: str) -> None:
|
|
client = DeepTutorApp()
|
|
success = await client.delete_session(session_id)
|
|
if not success:
|
|
console.print(f"[red]Session not found:[/] {session_id}")
|
|
raise typer.Exit(code=1)
|
|
console.print(f"Deleted session {session_id}")
|
|
|
|
|
|
async def _rename_session(session_id: str, title: str) -> None:
|
|
client = DeepTutorApp()
|
|
success = await client.rename_session(session_id, title)
|
|
if not success:
|
|
console.print(f"[red]Session not found:[/] {session_id}")
|
|
raise typer.Exit(code=1)
|
|
console.print(f"Renamed {session_id} -> {title}")
|