Coverage for src/lexigram/ai/cli/commands.py: 70%
43 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 07:19 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 07:19 +0800
1"""AI CLI command group factory."""
3from __future__ import annotations
5import typer
8def create_ai_app() -> typer.Typer:
9 """Create the `lexigram ai` command group.
11 Returns:
12 A Typer app containing AI subsystem management subcommands.
13 """
14 app = typer.Typer(help="AI subsystem management commands")
15 models_app = typer.Typer(help="Model management commands")
16 providers_app = typer.Typer(help="Provider management commands")
17 gateway_app = typer.Typer(help="AI relay gateway commands")
19 app.add_typer(models_app, name="models")
20 app.add_typer(providers_app, name="providers")
21 app.add_typer(gateway_app, name="gateway")
23 @gateway_app.command("check")
24 def gateway_check(
25 config: str = typer.Argument(..., help="Gateway config file (.json or .toml)"),
26 ) -> None:
27 """Validate a relay gateway configuration file."""
28 from lexigram.ai.cli.gateway import load_gateway_config
30 try:
31 loaded = load_gateway_config(config)
32 except ValueError as exc:
33 typer.echo(f"gateway config invalid: {exc}", err=True)
34 raise typer.Exit(code=1) from exc
35 typer.echo(
36 f"gateway config valid: {len(loaded.channels)} channel(s), "
37 f"load_balancing={loaded.load_balancing}"
38 )
40 @gateway_app.command("serve")
41 def gateway_serve(
42 config: str = typer.Argument(..., help="Gateway config file (.json or .toml)"),
43 host: str = typer.Option("127.0.0.1", "--host", help="Bind address"),
44 port: int = typer.Option(8000, "--port", help="Bind port"),
45 ) -> None:
46 """Assemble and serve the relay gateway application."""
47 from lexigram.ai.cli.gateway import serve_gateway
49 try:
50 serve_gateway(config, host=host, port=port)
51 except (ValueError, TypeError, ModuleNotFoundError) as exc:
52 typer.echo(f"cannot start gateway: {exc}", err=True)
53 raise typer.Exit(code=1) from exc
55 @app.command("status")
56 def ai_status() -> None:
57 """Show AI subsystem status."""
58 typer.echo("AI subsystem status not yet implemented")
60 @models_app.command("list")
61 def list_models(
62 provider: str | None = typer.Option(
63 None, "--provider", help="Filter by provider name"
64 ),
65 ) -> None:
66 """List available AI models."""
67 typer.echo("AI model listing not yet implemented")
69 @providers_app.command("list")
70 def list_providers() -> None:
71 """List registered AI providers."""
72 typer.echo("AI provider listing not yet implemented")
74 @app.command("config")
75 def config_show() -> None:
76 """Show current AI configuration."""
77 typer.echo("AI configuration display not yet implemented")
79 @app.command("test")
80 def test_provider(
81 provider: str = typer.Argument(..., help="Provider name to test"),
82 prompt: str = typer.Option(
83 "Hello, world!", "--prompt", help="Test prompt to send"
84 ),
85 ) -> None:
86 """Test a specific AI provider with a prompt."""
87 typer.echo(f"Testing provider {provider!r} not yet implemented")
89 return app