Metadata-Version: 2.4
Name: synoi-hermes-guard
Version: 0.2.0
Summary: SynOI governance plugin for the Hermes agent framework. Wires the SynOI gateway's per-tenant risk policy into Hermes's tool-call hook: allow, deny, or require human approval, per the policy you author. Companion to synoi-openclaw-guard.
Author-email: "SynOI Inc." <hello@synoi.systems>
License: AGPL-3.0-or-later
Project-URL: Homepage, https://synoi.systems
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Framework :: AsyncIO
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Dynamic: license-file

# synoi-hermes-guard

Python plugin for **Nous Research's Hermes** agent that consults the
SynOI gateway before any tool call executes, translated to Hermes's
tool-call extension API.

**Status:** Beta. The plugin, policy client, capability mapping, and receipt
handling are implemented, with 40 passing unit tests. End-to-end tests against a
live SynOI gateway exist but are skipped unless a gateway is reachable, so
integration against a running deployment is not covered by the unit suite.
The API may still change before 1.0.

Source is not yet public. See <https://synoi.systems>.

## What you get

- **Real-time HITL gates** on dangerous Hermes tool calls (`rm -rf`, `kubectl delete`, schema migrations, prod deploys, and so on)
- **Same risk policy** the gateway already uses on the LLM-call side
- **Per-tenant policy**, so different teams get different rules
- **Decision Receipts**: every gated call audit-trailed by the gateway
- **SMS approval**, dispatched by the gateway to the approver on file. SMS is the only approval channel implemented today; other surfaces are planned and not shipped
- **Capability mapping**, so your Hermes tool names (`bash_shell`, `code_executor`) map to canonical capabilities (`shell.command`, `code.execute`) and your gateway policy stays portable across agent frameworks

## Install

```bash
pip install synoi-hermes-guard
```

Requires a SynOI gateway to consult and a license key. See <https://synoi.systems>.

## Configure

Environment variables (see `synoi_hermes_guard/config.py`):

| Key | Required | Default | Description |
|---|---|---|---|
| `SYNOI_LICENSE_KEY` | yes | none | Your SynOI license |
| `SYNOI_GATEWAY_URL` | no | `http://localhost:3000` | Where the gateway runs |
| `SYNOI_GUARD_MODE` | no | `permissive` | `permissive` (fail-open) or `strict` (fail-closed) |
| `SYNOI_TENANT_ID` | no | derived from license | Tenant identifier |
| `SYNOI_TOOL_CAPABILITY_MAP` | no | identity | Path to YAML / JSON mapping file |
| `SYNOI_REQUEST_TIMEOUT_MS` | no | `2000` | HTTP timeout for the gateway check call |
| `SYNOI_WORKFLOW_POLL_INTERVAL_MS` | no | `1000` | How often to poll for `require_approval` resolution |
| `SYNOI_WORKFLOW_POLL_TIMEOUT_MS` | no | `300000` | Max wait for workflow resolution (5 min) |

## Capability mapping file

`synoi-hermes-guard.tool-map.yml`:

```yaml
mappings:
  bash_shell:        shell.command
  code_executor:     code.execute
  web_browser:       web.fetch
  file_writer:       fs.write
  database_query:    db.read
```

Then point `SYNOI_TOOL_CAPABILITY_MAP=./synoi-hermes-guard.tool-map.yml`.

Canonical capability names are what the gateway policy is written against, so a policy authored once stays portable as more agent frameworks are added.

## Failure modes

**permissive (default)**: if the license is invalid, the gateway is unreachable, or it returns an error, the plugin allows the tool call and logs a warning. The customer's agent never silently hangs because of SynOI infrastructure problems.

**strict**: the same conditions block the tool. Required for compliance use cases where governance is mandatory.

## Programmatic use

```python
from synoi_hermes_guard import HermesGuardPlugin, GuardConfig

plugin = HermesGuardPlugin()

# In your Hermes agent's tool-call interceptor:
verdict = await plugin.before_tool_call(
    tool_name="bash_shell",
    tool_input={"command": "kubectl delete pod payments-7f8d"},
    agent_context={"thread_id": "...", "user_id": "..."},
)

if verdict.block:
    # Don't run the tool. Stamp verdict.reason into the agent transcript.
    raise RuntimeError(f"Hermes Guard blocked tool call: {verdict.reason}")
else:
    # Proceed. Stamp verdict.receipt_id into the conversation log for audit.
    pass
```

Every gated call resolves against the same gateway endpoint and produces a
Decision Receipt, so the audit trail is uniform regardless of which agent
framework made the call.

## License

AGPL-3.0-or-later. See the LICENSE file included in this distribution.
