Spaces:
Runtime error
Runtime error
File size: 4,431 Bytes
0cac9cf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | """CLI argument parsing and interactive command normalization helpers."""
from rich.console import Console
from rich.prompt import Prompt
from rich.panel import Panel
from rich.table import Table
from rich import box
from .config import CliOptions
def print_help(console: Console) -> None:
"""Render CLI usage and available command-line options."""
help_table = Table(box=box.ROUNDED, show_header=False, show_edge=True, border_style="bright_magenta", pad_edge=False)
help_table.add_column("Option", style="bold cyan", no_wrap=True)
help_table.add_column("Description", style="white")
help_table.add_row("-h, --help", "Show this help message and exit")
help_table.add_row("-s, --setup", "Reconfigure provider/API key/model and save settings")
help_table.add_row("-p, --prompt", "Prompt text to send to the configured LLM")
help_table.add_row("-q, --quit", "Exit the session")
console.print(
Panel(
help_table,
title="[bold magenta]QueryQuest CLI[/bold magenta]",
border_style="bright_blue",
box=box.DOUBLE,
padding=(1, 2),
)
)
console.print(
Panel(
"[bold]Usage[/bold]\n[cyan]QQ[/cyan] [yellow]-s|--setup[/yellow] [yellow]-p|--prompt[/yellow] <text> [yellow]-q|--quit[/yellow]",
border_style="bright_green",
box=box.ROUNDED,
padding=(0, 1),
)
)
def print_banner(console: Console) -> None:
"""Render a short welcome banner for the interactive CLI."""
console.print(
Panel(
"[bold bright_magenta]QueryQuest[/bold bright_magenta]\n"
"[cyan]Your personal Excel agent[/cyan]",
border_style="bright_magenta",
box=box.ROUNDED,
padding=(1, 2),
)
)
def is_quit_command(text: str) -> bool:
"""Return True when text matches one of the accepted quit commands."""
value = text.strip().lower()
return value in {
"-q",
"--quit",
"qq -q",
"qq --quit",
"queryquest -q",
"queryquest --quit",
}
def normalize_prompt_input(text: str) -> tuple[str, bool]:
"""Normalize inline prompt syntax and detect empty `-p/--prompt` usage."""
value = text.strip()
if value in ("-p", "--prompt"):
return "", True
if value.startswith("-p ") or value.startswith("--prompt "):
parts = value.split(maxsplit=1)
if len(parts) == 2:
return parts[1].strip(), False
return value, False
def parse_args(argv: list[str], console: Console) -> CliOptions:
"""Parse command-line args, with interactive fallback for unknown/missing input."""
if not argv:
user_input = Prompt.ask("How can I help you today? (Tip: run [cyan]QQ -h[/cyan] for help.)", console=console).strip()
# Allow command-style entries in interactive mode, e.g. "qq -h" or "QQ -s".
parts = user_input.split(maxsplit=1)
has_prefix = bool(parts and parts[0].lower() in ("qq", "queryquest"))
if has_prefix:
user_input = parts[1].strip() if len(parts) == 2 else ""
if not has_prefix and user_input.startswith("-"):
console.print("Please prefix options with [cyan]qq[/cyan] or [cyan]QQ[/cyan] (example: [cyan]qq -h[/cyan]).")
return parse_args([], console)
if user_input in ("-h", "--help"):
print_help(console)
raise SystemExit(0)
if is_quit_command(user_input):
raise SystemExit(0)
if user_input in ("-s", "--setup"):
return CliOptions(setup=True, prompt=None)
if user_input in ("-p", "--prompt"):
return CliOptions(setup=False, prompt=Prompt.ask("Prompt", console=console).strip())
if user_input.startswith("-p ") or user_input.startswith("--prompt "):
parts = user_input.split(maxsplit=1)
if len(parts) == 2:
return CliOptions(setup=False, prompt=parts[1].strip())
return CliOptions(setup=False, prompt=user_input)
setup = False
prompt: str | None = None
i = 0
while i < len(argv):
arg = argv[i]
if arg in ("-h", "--help"):
print_help(console)
raise SystemExit(0)
if arg in ("-q", "--quit"):
raise SystemExit(0)
if arg in ("-s", "--setup"):
setup = True
i += 1
continue
if arg in ("-p", "--prompt"):
i += 1
if i >= len(argv):
console.print("Prompt value was missing. Switching to interactive mode selection.")
return parse_args([], console)
prompt = argv[i]
i += 1
continue
console.print(f"Unknown argument '{arg}'. Switching to interactive mode selection.")
return parse_args([], console)
return CliOptions(setup=setup, prompt=prompt)
def main() -> None:
"""Console entrypoint that delegates to the application bootstrap."""
from .app import main as app_main
app_main()
|