From 2f2e04381e90c0a018eeee03fdd6edc64a1ddeb5 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 12 Jun 2026 19:55:56 +0000 Subject: [PATCH] Add models command, rename endpoint to env, rebrand to OpenGradient Veil - New `og-veil models` lists models from the SDK's TEE_LLM enum (same source the server uses for GET /v1/models) - Rename `endpoint` command to `env` - Replace remaining "OpenGradient Local" mentions with "OpenGradient Veil" --- README.md | 4 ++-- tests/test_cli.py | 16 +++++++++++++--- uv.lock | 2 +- veil/__init__.py | 2 +- veil/cli.py | 35 ++++++++++++++++++++++++++--------- veil/server.py | 2 +- 6 files changed, 44 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f772ff4..b392605 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,8 @@ That's it. Every response is verified before you see it — check the on the body). Streaming works too; it's verified before the first token replays. Useful commands: `og-veil test` (send a one-off prompt to check the path), -`og-veil stop`, `og-veil status`, `og-veil endpoint` (re-prints the env vars), -`og-veil update`, `og-veil logout`. +`og-veil stop`, `og-veil status`, `og-veil env` (re-prints the env vars), +`og-veil models` (list available models), `og-veil update`, `og-veil logout`. ### Use it with Hermes Agent diff --git a/tests/test_cli.py b/tests/test_cli.py index b4a2783..b4ffd62 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,4 +1,4 @@ -"""CLI wiring: first-run login, session reuse, background-by-default, endpoint, update.""" +"""CLI wiring: first-run login, session reuse, background-by-default, env, models, update.""" from __future__ import annotations @@ -58,13 +58,23 @@ def test_setup_with_yes_starts_background(): assert result.exit_code == 0 -def test_endpoint_prints_env_vars(): +def test_env_prints_env_vars(): with mock.patch("veil.daemon.running_pid", return_value=4321): - result = CliRunner().invoke(cli.main, ["endpoint"]) + result = CliRunner().invoke(cli.main, ["env"]) assert "OPENAI_BASE_URL=http://127.0.0.1:11434/v1" in result.output assert result.exit_code == 0 +def test_models_lists_known_models(): + result = CliRunner().invoke(cli.main, ["models"]) + assert result.exit_code == 0 + # Should print at least one model name derived from the SDK's TEE_LLM enum. + from opengradient import TEE_LLM + + sample = next(iter(TEE_LLM)).value.split("/", 1)[1] + assert sample in result.output + + def test_test_command_posts_prompt_to_localhost_and_prints_reply(): resp = mock.MagicMock( status_code=200, diff --git a/uv.lock b/uv.lock index f5744e4..c576016 100644 --- a/uv.lock +++ b/uv.lock @@ -2111,7 +2111,7 @@ wheels = [ [[package]] name = "opengradient-veil" -version = "0.2.3" +version = "0.2.4" source = { editable = "." } dependencies = [ { name = "click" }, diff --git a/veil/__init__.py b/veil/__init__.py index ff7bbab..41a096b 100644 --- a/veil/__init__.py +++ b/veil/__init__.py @@ -1,4 +1,4 @@ -"""OpenGradient Local — self-verifying private-inference proxy for AI agents. +"""OpenGradient Veil — self-verifying private-inference proxy for AI agents. Point any OpenAI-compatible SDK at this process (one env var) and prompts are routed through OpenGradient's decentralized network of attestable AWS Nitro TEE diff --git a/veil/cli.py b/veil/cli.py index 2bc4bb4..46fa9a2 100644 --- a/veil/cli.py +++ b/veil/cli.py @@ -2,8 +2,8 @@ The common path is a single command: run ``og-veil`` and it logs you in on first use, then starts the local server in the background. Individual steps (``serve``, -``login``, ``stop``, ``status``, ``endpoint``, ``test``, ``update``, ``logout``) -are available on their own too. +``login``, ``stop``, ``status``, ``env``, ``models``, ``test``, ``update``, +``logout``) are available on their own too. """ from __future__ import annotations @@ -21,7 +21,7 @@ @click.option("-v", "--verbose", is_flag=True, help="Enable debug logging.") @click.pass_context def main(ctx: click.Context, verbose: bool) -> None: - """OpenGradient Local — drop-in, self-verifying private inference for AI agents. + """OpenGradient Veil — drop-in, self-verifying private inference for AI agents. Run with no command to do everything: set up on first run, then start the server. """ @@ -157,11 +157,11 @@ def _start_server(config: ServerConfig, *, foreground: bool) -> None: # Already running — surface that clearly rather than erroring out. existing = running_pid() if existing: - click.secho(f"OpenGradient Local is already running (pid {existing}).", fg="yellow") + click.secho(f"OpenGradient Veil is already running (pid {existing}).", fg="yellow") click.echo(" Stop it with: og-veil stop") return raise click.ClickException(str(exc)) - click.secho(f"✓ OpenGradient Local running in the background (pid {pid}).", fg="green") + click.secho(f"✓ OpenGradient Veil running in the background (pid {pid}).", fg="green") click.echo(f" Base URL : {config.advertised_base_url()}") click.echo(f" Logs : {log_path()}") click.echo(" Stop : og-veil stop") @@ -179,19 +179,36 @@ def stop() -> None: click.secho(f"✓ Stopped background server (pid {pid}).", fg="green") -@main.command() -def endpoint() -> None: - """Print the env vars to point your agent at OpenGradient Local.""" +@main.command(name="env") +def env_cmd() -> None: + """Print the env vars to point your agent at OpenGradient Veil.""" from veil.daemon import running_pid config = ServerConfig.from_env() - click.echo("Point your agent at OpenGradient Local (one env var change):") + click.echo("Point your agent at OpenGradient Veil (one env var change):") click.secho(f" export OPENAI_BASE_URL={config.advertised_base_url()}", bold=True) click.echo(" export OPENAI_API_KEY=og-veil # ignored; your Chat session authenticates") if running_pid() is None: click.echo("\nThe server isn't running yet — start it with `og-veil`.") +@main.command() +def models() -> None: + """List the models available through OpenGradient Veil. + + Derived from the SDK's canonical ``TEE_LLM`` enum — the same source the + local server uses for ``GET /v1/models`` — so it stays in sync with the + network as models are added or retired. + """ + from opengradient import TEE_LLM + + # Each enum value is ``provider/model``; agents send the bare model name. + names = sorted(m.value.split("/", 1)[1] for m in TEE_LLM) + click.echo("Models available through OpenGradient Veil:") + for name in names: + click.echo(f" {name}") + + @main.command(name="login") @click.option("--app-url", default=DEFAULT_APP_URL, show_default=True, help="Chat app web origin.") @click.option("--no-browser", is_flag=True, help="Don't open a browser; print the URL instead.") diff --git a/veil/server.py b/veil/server.py index 6af72e2..34ce890 100644 --- a/veil/server.py +++ b/veil/server.py @@ -150,7 +150,7 @@ def serve(config: ServerConfig) -> None: app = create_app(gateway) tee = gateway.active_tee print( - f"OpenGradient Local listening on http://{config.host}:{config.port}\n" + f"OpenGradient Veil listening on http://{config.host}:{config.port}\n" f" Verified TEE: {tee.tee_id if tee else '?'} ({tee.endpoint if tee else '?'})\n" f" Signed in as: {session.user_email or 'unknown'}\n\n" f"Point your agent at it (OpenAI SDK):\n"