Metadata-Version: 2.4
Name: edgegate-runner
Version: 0.2.0
Summary: EdgeGate self-hosted Behavioral-Gate device runner — runs the gate on a connected Snapdragon device and posts a signed verdict.
Requires-Python: >=3.10
Requires-Dist: certifi>=2024.0.0
Requires-Dist: cryptography<47,>=42.0.0
Requires-Dist: httpx>=0.26.0
Requires-Dist: jinja2>=3.1.0
Requires-Dist: pydantic-settings>=2.1.0
Requires-Dist: pydantic>=2.5.0
Requires-Dist: pynacl>=1.5.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: structlog>=24.1.0
Description-Content-Type: text/markdown

# edgegate-runner

Connect your edge device to [EdgeGate](https://edgegate.frozo.ai) — regression gates and a live device registry for on-device AI.

Works on any Linux/macOS box with Python 3.10+: NVIDIA Jetson, Snapdragon-connected hosts, Raspberry Pi, industrial gateways, laptops.

## Install

```bash
pip install edgegate-runner
```

## Connect a device (60 seconds)

1. In your EdgeGate workspace: **Settings → API Keys → Create key** (needs Pro tier). Copy the `egk_…` token.
2. On the device:

```bash
export EDGEGATE_TOKEN=egk_...                 # your workspace API key
export EDGEGATE_WORKSPACE_ID=<workspace-uuid> # shown in the dashboard URL / settings

edgegate-runner agent --vendor nvidia --silicon orin-nano-8gb --name my-jetson
```

The device appears in your workspace dashboard under **Device Targets** within seconds, with a live/offline badge driven by its 30-second heartbeat. Stop the agent and the badge flips to offline within ~90s.

`--vendor` is free-form (`qualcomm`, `nvidia`, `intel`, …); `--name` defaults to the hostname. Add `--once` for a smoke test that sends a single heartbeat and exits.

### Run it as a service (recommended)

```ini
# /etc/systemd/system/edgegate-agent.service
[Unit]
Description=EdgeGate device agent (liveness heartbeat)
After=network-online.target
Wants=network-online.target

[Service]
User=<your-user>
EnvironmentFile=/etc/edgegate-agent.env   # EDGEGATE_TOKEN=... EDGEGATE_WORKSPACE_ID=...
ExecStart=/usr/local/bin/edgegate-runner agent --vendor nvidia --name my-jetson
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

```bash
sudo systemctl enable --now edgegate-agent
```

## Behavioral Gate on NVIDIA Jetson (llama.cpp)

With `pip install llama-cpp-python` on the box, the runner executes Behavioral-Gate
runs against a GGUF model (vendor `nvidia`) — same eval sets, same scoring, same
signed verdict format as Snapdragon runs. Works online (`edgegate-runner run`)
and air-gapped (`edgegate-runner offline`).

## Behavioral-Gate runs (Snapdragon hosts)

On a host with a Snapdragon device attached via adb, the runner also executes EdgeGate Behavioral-Gate runs — pulling the run config and model bundle, running the gate on-device, and posting back a summary-only signed verdict (raw model output never leaves your box):

```bash
edgegate-runner run --run-id <run-id>
```

Air-gapped? `edgegate-runner offline --config config.json` runs entirely from local files.

## API and workflow endpoints (n8n, Zapier, Make, OpenAI-compatible)

New in 0.2.0. The gate is not limited to on-device models — it can target an HTTP
endpoint, so the thing under test can be an n8n workflow or any chat API.

EdgeGate runs these for you by default, with nothing to install. Use the runner
here when the endpoint sits on a private network EdgeGate cannot reach, or when
raw model output must never leave your infrastructure.

Capture a baseline from your endpoint:

```bash
edgegate-runner capture --config capture.json --out reference.json
```

```json
{
  "eval_set_path": "eval_set.yaml",
  "system_prompt": "You are a support workflow.",
  "decode_config": {},
  "http": {
    "endpoint_url": "https://your-n8n.example.com/webhook/support",
    "transport": "webhook",
    "request_template": {"chatInput": "{{prompt}}", "case_id": "{{case_id}}"},
    "response_text_path": "reply"
  }
}
```

Upload `reference.json` as the `golden` reference to certify the baseline, then
gate against it with `edgegate-runner run --run-id <run-id>`.

- `transport` is `webhook` or `openai_chat`.
- `response_text_path` is where the reply text lives in the response. Getting it
  wrong yields empty text, which scores as a refusal and would make every later
  run pass trivially — so capture refuses outright if every case comes back empty.
- The endpoint credential is read from `EDGEGATE_HTTP_API_KEY` in the runner's
  own environment. It is never sent to EdgeGate.
- Create the run with `execution: "runner"`. A run created as hosted is executed
  by EdgeGate, and the runner is refused it (409).

## Configuration

| Env var | Meaning | Default |
|---|---|---|
| `EDGEGATE_TOKEN` | Workspace API key (required) | — |
| `EDGEGATE_WORKSPACE_ID` | Workspace UUID (required) | — |
| `EDGEGATE_API_URL` | EdgeGate API base URL | `https://edgegateapi.frozo.ai` |

Docs: https://edgegate.frozo.ai/docs · © EdgeGate. Powered by Qualcomm AI Hub.
