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
104 lines
3.5 KiB
Python
104 lines
3.5 KiB
Python
"""
|
|
CLI commands for managing partner instances.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
import typer
|
|
|
|
console = Console()
|
|
|
|
|
|
def register(app: typer.Typer) -> None:
|
|
@app.command("list")
|
|
def partner_list() -> None:
|
|
"""List all partners."""
|
|
from deeptutor.services.partners import get_partner_manager
|
|
|
|
partners = get_partner_manager().list_partners()
|
|
if not partners:
|
|
console.print("[dim]No partners configured.[/]")
|
|
return
|
|
|
|
table = Table(title="Partners")
|
|
table.add_column("ID", style="cyan")
|
|
table.add_column("Name")
|
|
table.add_column("Status")
|
|
table.add_column("Model", style="dim")
|
|
table.add_column("Channels", style="dim")
|
|
|
|
for p in partners:
|
|
status = "[green]running[/]" if p.get("running") else "[dim]stopped[/]"
|
|
selection = p.get("llm_selection") or {}
|
|
model = selection.get("model_id") or p.get("model") or "(default)"
|
|
table.add_row(
|
|
p["partner_id"],
|
|
p.get("name", ""),
|
|
status,
|
|
model,
|
|
", ".join(p.get("channels", [])) or "-",
|
|
)
|
|
console.print(table)
|
|
|
|
@app.command("start")
|
|
def partner_start(
|
|
name: str = typer.Argument(..., help="Partner ID to start."),
|
|
) -> None:
|
|
"""Start a partner."""
|
|
from deeptutor.services.partners import get_partner_manager
|
|
|
|
mgr = get_partner_manager()
|
|
try:
|
|
instance = asyncio.run(mgr.start_partner(name))
|
|
console.print(f"[green]Started partner '{instance.config.name}' ({name})[/]")
|
|
except RuntimeError as e:
|
|
console.print(f"[red]Failed to start: {e}[/]")
|
|
raise typer.Exit(1)
|
|
|
|
@app.command("stop")
|
|
def partner_stop(
|
|
name: str = typer.Argument(..., help="Partner ID to stop."),
|
|
) -> None:
|
|
"""Stop a running partner."""
|
|
from deeptutor.services.partners import get_partner_manager
|
|
|
|
mgr = get_partner_manager()
|
|
stopped = asyncio.run(mgr.stop_partner(name))
|
|
if stopped:
|
|
console.print(f"[green]Stopped partner '{name}'[/]")
|
|
else:
|
|
console.print(f"[yellow]Partner '{name}' not found or not running.[/]")
|
|
|
|
@app.command("create")
|
|
def partner_create(
|
|
name: str = typer.Argument(..., help="Partner ID."),
|
|
display_name: str = typer.Option("", "--name", "-n", help="Display name."),
|
|
soul: str = typer.Option("", "--soul", "-s", help="Soul markdown (the persona)."),
|
|
model: str = typer.Option("", "--model", "-m", help="Model override."),
|
|
) -> None:
|
|
"""Create a new partner configuration and start it."""
|
|
from deeptutor.services.partners import get_partner_manager
|
|
from deeptutor.services.partners.manager import PartnerConfig
|
|
from deeptutor.services.partners.workspace import write_soul
|
|
|
|
config = PartnerConfig(
|
|
name=display_name or name,
|
|
model=model or None,
|
|
)
|
|
mgr = get_partner_manager()
|
|
try:
|
|
mgr.save_config(name, config, auto_start=True)
|
|
if soul:
|
|
write_soul(name, soul)
|
|
instance = asyncio.run(mgr.start_partner(name, config))
|
|
console.print(
|
|
f"[green]Created and started partner '{instance.config.name}' ({name})[/]"
|
|
)
|
|
except RuntimeError as e:
|
|
console.print(f"[red]Failed: {e}[/]")
|
|
raise typer.Exit(1)
|