superwise-sentinel-cli 0.3.0__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/CHANGELOG.md +12 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/PKG-INFO +1 -1
- superwise_sentinel_cli-0.3.1/build.env +1 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/pyproject.toml +1 -1
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/cli.py +34 -10
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/controller.py +16 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/docker_manager.py +8 -0
- superwise_sentinel_cli-0.3.0/build.env +0 -1
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/.gitignore +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/.gitlab-ci.yml +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/.pre-commit-config.yaml +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/.releaserc.json +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/CLAUDE.md +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/README.md +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/poetry.lock +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/poetry.toml +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/scripts/semantic-release-cli-publish.sh +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/__init__.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/auth.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/codex_profile.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/config.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/exceptions.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/shell_profile.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/__init__.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/test_auth.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/test_controller.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/test_docker_manager.py +0 -0
- {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/test_shell_profile.py +0 -0
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [0.3.0](https://gitlab.com/askboss/product/superwise/platform/sentinel-cli/compare/0.2.3...0.3.0) (2026-09-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### <!-- 1. -->:rocket: New Features
|
|
5
|
+
|
|
6
|
+
* configure codex ([16acd79](https://gitlab.com/askboss/product/superwise/platform/sentinel-cli/commit/16acd797fa82669ec3d195fbee8c50e1b4ab0055))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### <!-- 2. -->:bug: Bug Fixes
|
|
10
|
+
|
|
11
|
+
* configure sentinel-cli request timeout ([a2597b7](https://gitlab.com/askboss/product/superwise/platform/sentinel-cli/commit/a2597b742136bb5b05baa046e2a13340b75577cc))
|
|
12
|
+
|
|
1
13
|
## [0.2.3](https://gitlab.com/askboss/product/superwise/platform/sentinel-cli/compare/0.2.2...0.2.3) (2026-08-25)
|
|
2
14
|
|
|
3
15
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: superwise-sentinel-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Sentinel is an LLM proxy that intercepts traffic, enabling you to monitor, secure, and optimize your AI usage. This CLI tool helps you quickly set up traffic interception on this machine
|
|
5
5
|
Requires-Python: <4.0,>=3.11
|
|
6
6
|
Requires-Dist: click>=8.1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
RELEASED_VERSION=0.3.1
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "superwise-sentinel-cli"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "Sentinel is an LLM proxy that intercepts traffic, enabling you to monitor, secure, and optimize your AI usage. This CLI tool helps you quickly set up traffic interception on this machine"
|
|
9
9
|
requires-python = ">=3.11, <4.0"
|
|
10
10
|
dependencies = [
|
{superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/cli.py
RENAMED
|
@@ -13,6 +13,7 @@ from superwise_sentinel_cli.config import AppConfig
|
|
|
13
13
|
from superwise_sentinel_cli.config import CustomProvider
|
|
14
14
|
from superwise_sentinel_cli.config import VALID_APPS
|
|
15
15
|
from superwise_sentinel_cli.config import VALID_PROVIDERS
|
|
16
|
+
from superwise_sentinel_cli.controller import check_gateway_health
|
|
16
17
|
from superwise_sentinel_cli.controller import check_invalid_apps
|
|
17
18
|
from superwise_sentinel_cli.controller import check_invalid_providers
|
|
18
19
|
from superwise_sentinel_cli.controller import clear_env_vars
|
|
@@ -20,6 +21,7 @@ from superwise_sentinel_cli.controller import get_activation_url
|
|
|
20
21
|
from superwise_sentinel_cli.controller import get_proxy_status
|
|
21
22
|
from superwise_sentinel_cli.controller import get_running_gateway
|
|
22
23
|
from superwise_sentinel_cli.controller import get_sentinel_url
|
|
24
|
+
from superwise_sentinel_cli.controller import is_docker_running
|
|
23
25
|
from superwise_sentinel_cli.controller import needs_auth
|
|
24
26
|
from superwise_sentinel_cli.controller import parse_apps
|
|
25
27
|
from superwise_sentinel_cli.controller import parse_providers
|
|
@@ -105,10 +107,20 @@ def main() -> None:
|
|
|
105
107
|
@click.pass_context
|
|
106
108
|
def quickstart_flow(ctx, new_sentinel: bool) -> None:
|
|
107
109
|
"""Configure your first sentinel proxy."""
|
|
108
|
-
|
|
110
|
+
click.echo(
|
|
111
|
+
"""Welcome to SUPERWISE Sentinel!
|
|
112
|
+
The Sentinel proxy routes your local LLM traffic through a secure gateway, enabling guardrails and optimizations.
|
|
113
|
+
Select your gateway setup:
|
|
114
|
+
A) Provide the URL for an existing gateway.
|
|
115
|
+
B) Create a new gateway locally. Docker needs to be installed and running on this machine."""
|
|
116
|
+
)
|
|
117
|
+
if new_sentinel or not click.confirm("Do you have a URL for an existing gateway?"):
|
|
109
118
|
ctx.invoke(start_gateway, new_sentinel=new_sentinel)
|
|
110
119
|
else:
|
|
111
120
|
ctx.invoke(config_url)
|
|
121
|
+
gateway_text = click.style("gateway", fg="green")
|
|
122
|
+
proxy_text = click.style("proxy", fg="yellow")
|
|
123
|
+
click.echo(f"\nWith the {gateway_text} ready, let's customize our {proxy_text} traffic routing.")
|
|
112
124
|
ctx.invoke(config_providers)
|
|
113
125
|
ctx.invoke(config_apps)
|
|
114
126
|
ctx.invoke(start_proxy)
|
|
@@ -210,7 +222,9 @@ def start_gateway(
|
|
|
210
222
|
force: bool,
|
|
211
223
|
timeout_seconds: int | None,
|
|
212
224
|
) -> None:
|
|
213
|
-
"""Bootstrap & run a local Sentinel gateway container."""
|
|
225
|
+
"""Bootstrap & run a local Sentinel gateway container. Accessible only from this machine."""
|
|
226
|
+
if not is_docker_running():
|
|
227
|
+
raise click.ClickException("Docker is not responsive. Is it running?")
|
|
214
228
|
cfg = AppConfig.load()
|
|
215
229
|
|
|
216
230
|
if custom_providers:
|
|
@@ -259,13 +273,16 @@ def start_gateway(
|
|
|
259
273
|
|
|
260
274
|
if created_name:
|
|
261
275
|
click.echo(f"New sentinel '{created_name}' created. Sentinel ID: {cfg.sentinel_id}.")
|
|
276
|
+
local_notice = click.style("This gateway is local, and accessible only from this machine.", fg="cyan")
|
|
262
277
|
click.echo(
|
|
263
|
-
f"Gateway running on {url}
|
|
278
|
+
f"Gateway created and running on {url}!"
|
|
264
279
|
f"\nTo view Sentinel configuration and metrics, please visit {get_sentinel_url(cfg)}"
|
|
280
|
+
f"\n{local_notice}"
|
|
265
281
|
)
|
|
266
282
|
if timeout_seconds is not None:
|
|
267
283
|
click.echo(f"Timeout set to {timeout_seconds} seconds.")
|
|
268
|
-
click.
|
|
284
|
+
test_command = click.style('sentinel test --text "Your text here"', italic=True)
|
|
285
|
+
click.echo(f"\nWant to test it out? Run '{test_command}' to see it in action.")
|
|
269
286
|
|
|
270
287
|
|
|
271
288
|
@gateway.command("stop")
|
|
@@ -296,7 +313,12 @@ def update_gateway() -> None:
|
|
|
296
313
|
click.echo("Image is up to date.")
|
|
297
314
|
|
|
298
315
|
|
|
299
|
-
@main.group(
|
|
316
|
+
@main.group()
|
|
317
|
+
def proxy() -> None:
|
|
318
|
+
"""Toggle traffic interception."""
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
@proxy.group("config", invoke_without_command=True)
|
|
300
322
|
@click.option("--url", "url_value", default=None, help="Set the gateway URL non-interactively.")
|
|
301
323
|
@click.option(
|
|
302
324
|
"--providers",
|
|
@@ -412,11 +434,6 @@ def config_apps(set_value: str | None) -> None:
|
|
|
412
434
|
break
|
|
413
435
|
|
|
414
436
|
|
|
415
|
-
@main.group()
|
|
416
|
-
def proxy() -> None:
|
|
417
|
-
"""Toggle traffic interception."""
|
|
418
|
-
|
|
419
|
-
|
|
420
437
|
@proxy.command("on")
|
|
421
438
|
@click.pass_context
|
|
422
439
|
def start_proxy(ctx) -> None:
|
|
@@ -429,6 +446,13 @@ def start_proxy(ctx) -> None:
|
|
|
429
446
|
if not cfg.providers:
|
|
430
447
|
ctx.invoke(config_providers)
|
|
431
448
|
|
|
449
|
+
if not check_gateway_health(cfg.gateway_url):
|
|
450
|
+
click.echo(
|
|
451
|
+
f"Gateway at {cfg.gateway_url} did not respond in a timely manner."
|
|
452
|
+
f" Please verify it is healthy and try again."
|
|
453
|
+
)
|
|
454
|
+
return
|
|
455
|
+
|
|
432
456
|
cfg = AppConfig.load()
|
|
433
457
|
pairs = update_env_vars(cfg)
|
|
434
458
|
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
+
import time
|
|
5
6
|
|
|
6
7
|
import requests
|
|
7
8
|
from superwise_sentinel_cli.auth import authenticate
|
|
@@ -14,6 +15,7 @@ from superwise_sentinel_cli.config import VALID_APPS
|
|
|
14
15
|
from superwise_sentinel_cli.config import VALID_PROVIDERS
|
|
15
16
|
from superwise_sentinel_cli.docker_manager import ensure_container_running
|
|
16
17
|
from superwise_sentinel_cli.docker_manager import get_running_gateway_info
|
|
18
|
+
from superwise_sentinel_cli.docker_manager import is_docker_running
|
|
17
19
|
from superwise_sentinel_cli.docker_manager import pull_latest_image
|
|
18
20
|
from superwise_sentinel_cli.docker_manager import stop_container
|
|
19
21
|
from superwise_sentinel_cli.exceptions import AuthenticationError
|
|
@@ -156,6 +158,20 @@ def update_env_vars(cfg: AppConfig) -> list[tuple[str, str]]:
|
|
|
156
158
|
return pairs
|
|
157
159
|
|
|
158
160
|
|
|
161
|
+
def check_gateway_health(gateway_url: str, retries: int = 3, delay_seconds: float = 1.0) -> bool:
|
|
162
|
+
url = gateway_url.rstrip("/") + "/healthz"
|
|
163
|
+
for attempt in range(retries):
|
|
164
|
+
try:
|
|
165
|
+
resp = requests.get(url, timeout=5)
|
|
166
|
+
if resp.ok:
|
|
167
|
+
return True
|
|
168
|
+
except requests.RequestException:
|
|
169
|
+
pass
|
|
170
|
+
if attempt < retries - 1:
|
|
171
|
+
time.sleep(delay_seconds)
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
|
|
159
175
|
def write_codex_config(cfg: AppConfig) -> bool:
|
|
160
176
|
if "openai" not in cfg.providers or "codex" not in cfg.apps:
|
|
161
177
|
return False
|
|
@@ -35,6 +35,14 @@ def _docker_client() -> docker.DockerClient:
|
|
|
35
35
|
raise DockerUnavailableError() from exc
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def is_docker_running() -> bool:
|
|
39
|
+
try:
|
|
40
|
+
_docker_client()
|
|
41
|
+
return True
|
|
42
|
+
except DockerUnavailableError:
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
|
|
38
46
|
def _running_container(client: docker.DockerClient) -> Container | None:
|
|
39
47
|
matches = client.containers.list(filters={"name": CONTAINER_NAME, "status": "running"})
|
|
40
48
|
return matches[0] if matches else None
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
RELEASED_VERSION=0.3.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/__init__.py
RENAMED
|
File without changes
|
{superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/auth.py
RENAMED
|
File without changes
|
|
File without changes
|
{superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|