Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions projects/openshell-agent-runner/docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ agent_markdown: true

| Command | Purpose |
| --- | --- |
| `oar --version` | Display the installed OAR version. |
| `oar init PROFILE_ROOT --model MODEL_ID` | Create editable copies of the packaged profiles. |
| `oar validate PROFILE_DIRECTORY` | Check the profile and its local resources. |
| `oar doctor` | Display the OpenShell version, gateway status, and inference configuration. |
Expand Down
32 changes: 32 additions & 0 deletions projects/openshell-agent-runner/src/openshell_agent_runner/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from __future__ import annotations

import shlex
from importlib.metadata import PackageNotFoundError
from importlib.metadata import version as distribution_version
from pathlib import Path
from typing import Annotated, NoReturn

Expand All @@ -20,6 +22,14 @@
from openshell_agent_runner.profile_init import ThinkingLevel, initialize_profiles
from openshell_agent_runner.runner import RunRequest, render_dry_run, run_agent


def version_callback(value: bool) -> None:
"""Print the installed OAR version when requested."""
if value:
typer.echo(f"oar {_installed_version()}")
raise typer.Exit()


app = typer.Typer(
help="Launch ephemeral agents for single tasks in OpenShell sandboxes.",
no_args_is_help=True,
Expand All @@ -28,6 +38,21 @@
)


@app.callback()
def main(
version: Annotated[
bool | None,
typer.Option(
"--version",
callback=version_callback,
is_eager=True,
help="Show the installed OAR version and exit.",
),
] = None,
) -> None:
"""Launch ephemeral agents for single tasks in OpenShell sandboxes."""


class ProfileTaskHelpCommand(TyperCommand):
"""Show focused help when a profile task is selected."""

Expand Down Expand Up @@ -215,6 +240,13 @@ def _fail(error: OarError) -> NoReturn:
raise typer.Exit(1)


def _installed_version() -> str:
try:
return distribution_version("openshell-agent-runner")
except PackageNotFoundError:
return "unknown"


def _profile_task_selection(args: list[str]) -> tuple[Path, str] | None:
if not args or args[0].startswith("-"):
return None
Expand Down
29 changes: 28 additions & 1 deletion projects/openshell-agent-runner/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# SPDX-License-Identifier: Apache-2.0

import shutil
from importlib.metadata import PackageNotFoundError
from importlib.metadata import version as distribution_version
from pathlib import Path

import pytest
Expand All @@ -26,8 +28,33 @@ def test_root_help_lists_commands() -> None:
result = CliRunner().invoke(app, ["--help"])

assert result.exit_code == 0
help_text = Text.from_ansi(result.stdout).plain
for command in ("init", "validate", "run", "doctor"):
assert command in result.stdout
assert command in help_text
assert "--version" in help_text


def test_version_reports_installed_distribution_version() -> None:
result = CliRunner().invoke(app, ["--version"])

assert result.exit_code == 0
assert result.stdout == f"oar {distribution_version('openshell-agent-runner')}\n"


def test_version_handles_unavailable_distribution_metadata(
monkeypatch: pytest.MonkeyPatch,
) -> None:
def missing_distribution(_distribution_name: str) -> str:
raise PackageNotFoundError

monkeypatch.setattr(
"openshell_agent_runner.cli.distribution_version", missing_distribution
)

result = CliRunner().invoke(app, ["--version"])

assert result.exit_code == 0
assert result.stdout == "oar unknown\n"


@pytest.mark.parametrize(
Expand Down
Loading