atbash-hermes-plugin 0.1.7.dev0__tar.gz → 0.1.8.dev0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atbash-hermes-plugin
3
- Version: 0.1.7.dev0
3
+ Version: 0.1.8.dev0
4
4
  Summary: Atbash safety plugin for Hermes Agent
5
5
  Author: atbash
6
6
  License-Expression: LicenseRef-Atbash-Proprietary
@@ -10,7 +10,7 @@ Keywords: atbash,hermes,hermes-agent,agent-safety,ai-safety,tool-guard,judge,pol
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
- Requires-Dist: atbash-sdk==0.1.7.dev0
13
+ Requires-Dist: atbash-sdk==0.1.8.dev0
14
14
  Requires-Dist: httpx<1,>=0.27
15
15
  Requires-Dist: opentelemetry-exporter-otlp-proto-http<2,>=1.29
16
16
  Requires-Dist: opentelemetry-sdk<2,>=1.29
@@ -38,13 +38,13 @@ stopped before execution.
38
38
  Install the plugin into the same Python environment that runs Hermes:
39
39
 
40
40
  ```bash
41
- pip install --pre atbash-hermes-plugin==0.1.7.dev0
41
+ pip install --pre atbash-hermes-plugin==0.1.8.dev0
42
42
  ```
43
43
 
44
44
  If Hermes is installed in a virtual environment, use that environment's Python:
45
45
 
46
46
  ```bash
47
- /path/to/hermes/venv/bin/python -m pip install --pre atbash-hermes-plugin==0.1.7.dev0
47
+ /path/to/hermes/venv/bin/python -m pip install --pre atbash-hermes-plugin==0.1.8.dev0
48
48
  ```
49
49
 
50
50
  ## Configure Atbash
@@ -20,13 +20,13 @@ stopped before execution.
20
20
  Install the plugin into the same Python environment that runs Hermes:
21
21
 
22
22
  ```bash
23
- pip install --pre atbash-hermes-plugin==0.1.7.dev0
23
+ pip install --pre atbash-hermes-plugin==0.1.8.dev0
24
24
  ```
25
25
 
26
26
  If Hermes is installed in a virtual environment, use that environment's Python:
27
27
 
28
28
  ```bash
29
- /path/to/hermes/venv/bin/python -m pip install --pre atbash-hermes-plugin==0.1.7.dev0
29
+ /path/to/hermes/venv/bin/python -m pip install --pre atbash-hermes-plugin==0.1.8.dev0
30
30
  ```
31
31
 
32
32
  ## Configure Atbash
@@ -4,6 +4,7 @@ import atexit
4
4
  import json
5
5
  import logging
6
6
  import os
7
+ import re
7
8
  from pathlib import Path
8
9
  from typing import Any, Dict, Optional
9
10
 
@@ -65,6 +66,98 @@ def _save_tool_map(path: Path, tool_map: Dict[str, str]) -> None:
65
66
 
66
67
 
67
68
 
69
+ _ERC20_RE = re.compile(r"\b(0x[0-9a-fA-F]{40})\b")
70
+ _ERC20_ADDR_RE = re.compile(r"(0x[0-9a-fA-F]{40})")
71
+ _FINANCIAL_OP_RE = re.compile(r"\b(transfer|send|swap|approve|erc20)\b", re.IGNORECASE)
72
+
73
+ _ASSET_BY_CONTRACT: Dict[str, str] = {
74
+ "0xdac17f958d2ee523a2206206994597c13d831ec7": "USDT",
75
+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": "USDC",
76
+ "0x6b175474e89094c44da98b954eedeac495271d0f": "DAI",
77
+ "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2": "WETH",
78
+ "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599": "WBTC",
79
+ "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984": "UNI",
80
+ "0x514910771af9ca656af840dff83e8264ecf986ca": "LINK",
81
+ "0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9": "AAVE",
82
+ "0xb0df6379ba1692841965a0745ac1bd3046d79ba3": "ATBASH",
83
+ "0xe9c094187219d9a29382c1a36fc43619c9257777": "ATBASH",
84
+ "0xf8b071428558c657a7a9aa1c43e152e75dd77777": "ATBASH",
85
+ }
86
+
87
+
88
+ def _load_recipient_allowlist() -> set:
89
+ try:
90
+ p = Path("~/.config/atbash/recipient-allowlist.json").expanduser()
91
+ data = json.loads(p.read_text(encoding="utf-8"))
92
+ return {str(a).lower() for a in data} if isinstance(data, list) else set()
93
+ except Exception:
94
+ return set()
95
+
96
+
97
+ def _resolve_asset(token: str) -> str:
98
+ if not token:
99
+ return "ETH"
100
+ t = token.lower()
101
+ m = _ERC20_ADDR_RE.search(t)
102
+ if m:
103
+ return _ASSET_BY_CONTRACT.get(m.group(1).lower(), "other")
104
+ if t in ("c60", "eth"):
105
+ return "ETH"
106
+ if t == "atbash":
107
+ return "ATBASH"
108
+ if t in ("usdt", "tether"):
109
+ return "USDT"
110
+ if t == "usdc":
111
+ return "USDC"
112
+ return "other"
113
+
114
+
115
+ def _canonicalize_financial(command: str, recipient_allowlist: set) -> Optional[Dict[str, Any]]:
116
+ if not command:
117
+ return None
118
+ has_financial = bool(_FINANCIAL_OP_RE.search(command))
119
+ has_address = bool(_ERC20_RE.search(command))
120
+ if not has_financial and not has_address:
121
+ return None
122
+
123
+ def _flag(name: str) -> Optional[str]:
124
+ m = re.search(rf"--{name}[= ]+(\S+)", command)
125
+ return m.group(1).strip("'\"") if m else None
126
+
127
+ token = _flag("token")
128
+ if not token:
129
+ m = _ERC20_RE.search(command)
130
+ if m:
131
+ token = m.group(1)
132
+
133
+ to = _flag("to") or _flag("recipient")
134
+ amount = _flag("amount")
135
+ max_usd = _flag("max-usd")
136
+ asset = _resolve_asset(token or "")
137
+
138
+ on_allow = bool(to) and to.lower() in recipient_allowlist
139
+ if asset == "USDT":
140
+ recipient_status = "allowlisted" if on_allow else ("external-not-allowlisted" if to else "unspecified")
141
+ else:
142
+ recipient_status = "external" if to else "unspecified"
143
+
144
+ op = (
145
+ "swap" if re.search(r"\bswap\b", command, re.IGNORECASE)
146
+ else "approve" if re.search(r"\b(approve|erc20)\b", command, re.IGNORECASE)
147
+ else "transfer"
148
+ )
149
+
150
+ return {
151
+ "operation": op,
152
+ "asset": asset,
153
+ "amount": amount,
154
+ "max_usd": max_usd,
155
+ "recipient_status": recipient_status,
156
+ "allowlist_scope": "USDT transfers/approvals only; never lifts ETH or ATBASH rules",
157
+ "note": "canonicalized pre-judge; raw 0x addresses omitted (redacted upstream)",
158
+ }
159
+
160
+
68
161
  def _extract_command(tool_name: str, tool_args: Dict[str, Any]) -> str:
69
162
  if not isinstance(tool_args, dict):
70
163
  return ""
@@ -213,6 +306,7 @@ class AtbashHermesGuard:
213
306
  os.getenv("ATBASH_TOOL_MAP_PATH", str(_default_tool_map_path()))
214
307
  ).expanduser()
215
308
  self.tool_map = {**DEFAULT_TOOL_CLASS_MAP, **_load_tool_map(self.tool_map_path)}
309
+ self.recipient_allowlist = _load_recipient_allowlist()
216
310
 
217
311
  self.client = self._build_client()
218
312
 
@@ -240,7 +334,7 @@ class AtbashHermesGuard:
240
334
  from atbash import Atbash # type: ignore
241
335
  from atbash.types import ToolCallInput # type: ignore
242
336
  except Exception:
243
- raise RuntimeError("atbash-sdk is required. Install with: pip install atbash-sdk==0.1.7.dev0") from e
337
+ raise RuntimeError("atbash-sdk is required. Install with: pip install atbash-sdk==0.1.8.dev0") from e
244
338
 
245
339
  self.ToolCallInput = ToolCallInput
246
340
  judge_cfg = self._judge_config()
@@ -326,13 +420,14 @@ class AtbashHermesGuard:
326
420
  "args": tool_args or {},
327
421
  }
328
422
 
329
- return self.client.audit_tool_call(
330
- self.ToolCallInput(
331
- tool_name=tool_name or "unknown",
332
- args=action_payload,
333
- context=context,
334
- )
423
+ resolved = _canonicalize_financial(command, self.recipient_allowlist)
424
+ tci = self.ToolCallInput(
425
+ tool_name=tool_name or "unknown",
426
+ args=action_payload,
427
+ context=context,
428
+ resolved=resolved,
335
429
  )
430
+ return self.client.audit_tool_call(tci)
336
431
 
337
432
  def pre_tool_call(
338
433
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atbash-hermes-plugin
3
- Version: 0.1.7.dev0
3
+ Version: 0.1.8.dev0
4
4
  Summary: Atbash safety plugin for Hermes Agent
5
5
  Author: atbash
6
6
  License-Expression: LicenseRef-Atbash-Proprietary
@@ -10,7 +10,7 @@ Keywords: atbash,hermes,hermes-agent,agent-safety,ai-safety,tool-guard,judge,pol
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
- Requires-Dist: atbash-sdk==0.1.7.dev0
13
+ Requires-Dist: atbash-sdk==0.1.8.dev0
14
14
  Requires-Dist: httpx<1,>=0.27
15
15
  Requires-Dist: opentelemetry-exporter-otlp-proto-http<2,>=1.29
16
16
  Requires-Dist: opentelemetry-sdk<2,>=1.29
@@ -38,13 +38,13 @@ stopped before execution.
38
38
  Install the plugin into the same Python environment that runs Hermes:
39
39
 
40
40
  ```bash
41
- pip install --pre atbash-hermes-plugin==0.1.7.dev0
41
+ pip install --pre atbash-hermes-plugin==0.1.8.dev0
42
42
  ```
43
43
 
44
44
  If Hermes is installed in a virtual environment, use that environment's Python:
45
45
 
46
46
  ```bash
47
- /path/to/hermes/venv/bin/python -m pip install --pre atbash-hermes-plugin==0.1.7.dev0
47
+ /path/to/hermes/venv/bin/python -m pip install --pre atbash-hermes-plugin==0.1.8.dev0
48
48
  ```
49
49
 
50
50
  ## Configure Atbash
@@ -1,4 +1,4 @@
1
- atbash-sdk==0.1.7.dev0
1
+ atbash-sdk==0.1.8.dev0
2
2
  httpx<1,>=0.27
3
3
  opentelemetry-exporter-otlp-proto-http<2,>=1.29
4
4
  opentelemetry-sdk<2,>=1.29
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "atbash-hermes-plugin"
7
- version = "0.1.7.dev0"
7
+ version = "0.1.8.dev0"
8
8
  description = "Atbash safety plugin for Hermes Agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -24,7 +24,7 @@ keywords = [
24
24
  "policy"
25
25
  ]
26
26
  dependencies = [
27
- "atbash-sdk==0.1.7.dev0",
27
+ "atbash-sdk==0.1.8.dev0",
28
28
  "httpx>=0.27,<1",
29
29
  "opentelemetry-exporter-otlp-proto-http>=1.29,<2",
30
30
  "opentelemetry-sdk>=1.29,<2",