Source code for ooai_llm.cli.help

"""Shared CLI help text and parser helpers.

Purpose:
    Keep the command-line interface teachable without letting ``cli.py`` grow
    into a pile of duplicated help strings and option builders.
"""

from __future__ import annotations

import argparse
from decimal import Decimal
from importlib.metadata import PackageNotFoundError, version as metadata_version

[docs] MODEL_CAPABILITY_CHOICES = ( "chat", "reasoning", "coding", "vision", "function_calling", "tool_calling", "tool_choice", "parallel_tool_calls", "structured_output", "cheap", )
[docs] MODEL_CATALOG_SORT_CHOICES = ( "recency", "provider", "model", "cost", "input_cost", "output_cost", "context", "input_tokens", "output_tokens", )
[docs] MODEL_COMPARE_SORT_CHOICES = ( "call_cost", "cost", "calls", "calls_per_usd", "provider", "model", "input_tokens", "output_tokens", "context", )
[docs] LCB_PRO_DIFFICULTY_CHOICES = ("easy", "medium", "hard")
[docs] LCB_PRO_SORT_CHOICES = ("rating", "provider", "organization", "model", "status")
[docs] ROOT_HELP = """\ Utilities for choosing, comparing, configuring, and inspecting LLMs. Mental model: Catalog/suite choose and compare models ChatModelProfile serialize model configuration LLM invoke a model and record observed usage/cost """
[docs] ROOT_EXAMPLES = """\ Common tasks: List cheap Mistral models: ooai-llm models cheapest --providers mistral --limit 10 Compare coding-capable models for a 10k/2k call: ooai-llm models coding --providers openai,anthropic,mistral --input-tokens 10000 --output-tokens 2000 Find tool + structured-output models: ooai-llm models list --source litellm --tool-calling-only --structured-output-only --sort output_tokens Explore the full raw LiteLLM registry: ooai-llm models list --all-litellm --format table ooai-llm tui --catalog-all Build a reusable model suite: ooai-llm models suite --suite comparison --providers openai,anthropic,mistral Validate and resolve a serializable profile: ooai-llm profiles validate --input profile.json ooai-llm profiles resolve --input profile.json --format json Print copy/paste CLI and Python recipes: ooai-llm recipes --topic coding ooai-llm recipes --topic rich Launch the optional interactive explorer: ooai-llm tui --theme paper ooai-llm tui --providers mistral --views cheapest,catalog --limit 10 Use --format json or --format csv for automation. Use --no-rich for deterministic plain tables. """
[docs] MODELS_EXAMPLES = """\ Examples: ooai-llm models cheapest --providers mistral --limit 10 ooai-llm models coding --providers openai,anthropic,mistral --tool-calling-only ooai-llm models list --source litellm --providers openai,mistral --sort cost --limit 0 ooai-llm models list --all-litellm --providers openrouter --limit 0 ooai-llm models compare --source litellm --providers mistral --input-tokens 10000 --output-tokens 2000 ooai-llm models suite --from-catalog --coding-only --sort cost --limit 5 """
[docs] MODEL_LIST_EXAMPLES = """\ Examples: ooai-llm models list --source litellm --providers mistral --sort cost --limit 0 ooai-llm models list --all-litellm --limit 0 ooai-llm models list --all-litellm --providers fireworks_ai,openrouter --limit 0 ooai-llm models list --source litellm --tool-calling-only --structured-output-only --sort output_tokens ooai-llm models list --source litellm --released-after 2026-01 --min-input-tokens 128000 """
[docs] MODEL_COMPARE_EXAMPLES = """\ Examples: ooai-llm models compare --source litellm --providers mistral --input-tokens 10000 --output-tokens 2000 ooai-llm models compare --source litellm --providers openai,anthropic,mistral --baseline openai:gpt-5-mini ooai-llm models compare --source litellm --coding-only --tool-calling-only --sort call_cost """
[docs] MODEL_CHEAPEST_EXAMPLES = """\ Examples: ooai-llm models cheapest --providers mistral --limit 10 ooai-llm models cheapest --providers openai,anthropic,google,deepseek,mistral --per-provider ooai-llm models cheapest --structured-output-only --input-tokens 5000 --output-tokens 1000 --budget-usd 20 """
[docs] MODEL_CODING_EXAMPLES = """\ Examples: ooai-llm models coding --providers mistral --limit 10 ooai-llm models coding --providers openai,anthropic,google,deepseek,mistral --per-provider ooai-llm models coding --tool-calling-only --structured-output-only --min-output-tokens 8000 """
[docs] MODEL_SUITE_EXAMPLES = """\ Examples: ooai-llm models suite --suite comparison --providers openai,anthropic,mistral ooai-llm models suite --from-catalog --coding-only --sort cost --limit 5 ooai-llm models suite --suite comparison --parallel-tool-calls false --format json """
[docs] PROFILES_EXAMPLES = """\ Examples: ooai-llm profiles validate --input profile.json ooai-llm profiles render --input profile.json ooai-llm profiles resolve --input profile.json --format json """
[docs] BENCHMARKS_EXAMPLES = """\ Examples: ooai-llm benchmarks lcb-pro summary ooai-llm benchmarks lcb-pro models --status active --limit 10 ooai-llm benchmarks lcb-pro difficulty --difficulty hard --provider openai """
[docs] def package_version() -> str: """Return the installed package version for ``--version`` output.""" try: return metadata_version("ooai-llm") except PackageNotFoundError: return "0.0.0"
[docs] def add_provider_args(command: argparse.ArgumentParser, *, noun: str = "Provider") -> None: """Add repeatable and comma-separated provider options.""" command.add_argument( "--provider", action="append", default=[], help=f"{noun} to include. Can be repeated.", ) command.add_argument( "--providers", action="append", default=[], help=f"Comma-separated {noun.lower()} list.", )
[docs] def add_catalog_filter_args(command: argparse.ArgumentParser, *, context_word: str = "show") -> None: """Add common model catalog filters used by list/compare/suite commands.""" command.add_argument( "--include-non-chat", action="store_true", help="Include embeddings, image, audio, and other non-chat models.", ) command.add_argument( "--capability", action="append", choices=MODEL_CAPABILITY_CHOICES, default=[], help="Required capability filter. Can be repeated.", ) command.add_argument("--reasoning-only", action="store_true", help=f"Only {context_word} reasoning-oriented models.") command.add_argument("--coding-only", action="store_true", help=f"Only {context_word} coding-oriented models.") command.add_argument("--vision-only", action="store_true", help=f"Only {context_word} vision-capable models.") command.add_argument( "--function-calling-only", action="store_true", help=f"Only {context_word} models marked as function/tool-call capable.", ) command.add_argument( "--tool-calling-only", action="store_true", help=f"Only {context_word} models marked as tool-call capable.", ) command.add_argument( "--tool-choice-only", action="store_true", help=f"Only {context_word} models marked as explicit tool-choice capable.", ) command.add_argument( "--parallel-tool-calls-only", action="store_true", help=f"Only {context_word} models marked as parallel-tool-call capable.", ) command.add_argument( "--structured-output-only", action="store_true", help=f"Only {context_word} models marked as native structured-output capable.", ) command.add_argument( "--min-context", type=int, default=None, help="Only include models with at least this many input/context tokens.", ) command.add_argument( "--min-input-tokens", dest="min_context", type=int, default=None, help="Alias for --min-context.", ) command.add_argument( "--min-output-tokens", type=int, default=None, help="Only include models with at least this many output tokens.", ) command.add_argument( "--max-input-cost-per-1m", type=Decimal, default=None, help="Only include models at or below this input-token USD cost per 1M tokens.", ) command.add_argument( "--max-output-cost-per-1m", type=Decimal, default=None, help="Only include models at or below this output-token USD cost per 1M tokens.", ) command.add_argument("--released-after", default=None, help="Catalog lower release-date bound.") command.add_argument("--released-before", default=None, help="Catalog upper release-date bound.")
[docs] def add_compare_args( command: argparse.ArgumentParser, *, default_sort: str = "call_cost", default_limit: int = 20, ) -> None: """Add common cost-comparison options.""" command.add_argument( "--source", choices=("auto", "provider", "litellm"), default="auto", help="Catalog source. Defaults to auto.", ) add_provider_args(command, noun="Provider") command.add_argument( "--format", choices=("table", "json", "csv"), default="table", help="Output format. Defaults to table.", ) command.add_argument( "--style", choices=("langchain", "litellm", "bare"), default="langchain", help="Model-string style for table and CSV output.", ) command.add_argument( "--limit", type=int, default=default_limit, help="Maximum rows after ranking. Use 0 for no limit.", ) command.add_argument( "--input-tokens", type=int, default=10_000, help="Representative input tokens per call. Defaults to 10000.", ) command.add_argument( "--output-tokens", type=int, default=2_000, help="Representative output tokens per call. Defaults to 2000.", ) command.add_argument( "--budget-usd", type=Decimal, default=Decimal("1"), help="Budget for calls-per-budget estimates. Defaults to 1.", ) command.add_argument( "--baseline", default=None, help="Optional model used to compute calls-per-baseline ratios.", ) command.add_argument( "--per-provider", action="store_true", help="Only keep the cheapest matching model for each provider.", ) add_catalog_filter_args(command, context_word="compare") command.add_argument( "--sort", choices=MODEL_COMPARE_SORT_CHOICES, default=default_sort, help=f"Sort comparison rows. Defaults to {default_sort}.", ) command.add_argument("--strict", action="store_true", help="Fail if any selected provider cannot be listed.") command.add_argument( "--no-rich", action="store_true", help="Use the built-in plain table renderer even when Rich is installed.", )