humanbound 2.0.2__tar.gz → 2.0.3__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.
Files changed (109) hide show
  1. {humanbound-2.0.2 → humanbound-2.0.3}/PKG-INFO +5 -5
  2. {humanbound-2.0.2 → humanbound-2.0.3}/README.md +4 -4
  3. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound.egg-info/PKG-INFO +5 -5
  4. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/client.py +11 -1
  5. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/presenter.py +0 -7
  6. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/runner.py +1 -1
  7. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/schemas.py +2 -8
  8. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/mcp_server.py +3 -6
  9. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/report.py +1 -1
  10. {humanbound-2.0.2 → humanbound-2.0.3}/pyproject.toml +1 -1
  11. {humanbound-2.0.2 → humanbound-2.0.3}/LICENSE +0 -0
  12. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound/__init__.py +0 -0
  13. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound/bot.py +0 -0
  14. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound/callbacks.py +0 -0
  15. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound/orchestrators.py +0 -0
  16. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound/py.typed +0 -0
  17. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound/runner.py +0 -0
  18. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound/schemas.py +0 -0
  19. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound.egg-info/SOURCES.txt +0 -0
  20. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound.egg-info/dependency_links.txt +0 -0
  21. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound.egg-info/entry_points.txt +0 -0
  22. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound.egg-info/requires.txt +0 -0
  23. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound.egg-info/top_level.txt +0 -0
  24. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/__init__.py +0 -0
  25. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/adapters/__init__.py +0 -0
  26. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/adapters/promptfoo.py +0 -0
  27. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/adapters/pyrit.py +0 -0
  28. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/__init__.py +0 -0
  29. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/_report_helper.py +0 -0
  30. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/api_keys.py +0 -0
  31. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/assessments.py +0 -0
  32. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/auth.py +0 -0
  33. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/campaigns.py +0 -0
  34. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/completion.py +0 -0
  35. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/config_cmd.py +0 -0
  36. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/connect.py +0 -0
  37. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/docs.py +0 -0
  38. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/experiments.py +0 -0
  39. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/findings.py +0 -0
  40. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/firewall.py +0 -0
  41. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/guardrails.py +0 -0
  42. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/logs.py +0 -0
  43. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/mcp.py +0 -0
  44. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/members.py +0 -0
  45. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/monitor.py +0 -0
  46. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/orgs.py +0 -0
  47. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/posture.py +0 -0
  48. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/projects.py +0 -0
  49. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/providers.py +0 -0
  50. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/redteam.py +0 -0
  51. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/report.py +0 -0
  52. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/scan.py +0 -0
  53. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/sentinel.py +0 -0
  54. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/test.py +0 -0
  55. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/upload_logs.py +0 -0
  56. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/commands/webhooks.py +0 -0
  57. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/config.py +0 -0
  58. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/connectors/__init__.py +0 -0
  59. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/connectors/microsoft.py +0 -0
  60. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/__init__.py +0 -0
  61. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/bot.py +0 -0
  62. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/callbacks.py +0 -0
  63. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/compliance.py +0 -0
  64. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/llm/__init__.py +0 -0
  65. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/llm/azureopenai.py +0 -0
  66. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/llm/claude.py +0 -0
  67. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/llm/gemini.py +0 -0
  68. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/llm/grok.py +0 -0
  69. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/llm/ollama.py +0 -0
  70. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/llm/openai.py +0 -0
  71. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/local_runner.py +0 -0
  72. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/__init__.py +0 -0
  73. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/base.py +0 -0
  74. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/behavioral_qa/__init__.py +0 -0
  75. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/behavioral_qa/config.py +0 -0
  76. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/behavioral_qa/generator.py +0 -0
  77. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/behavioral_qa/judge.py +0 -0
  78. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/behavioral_qa/orchestrator.py +0 -0
  79. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_agentic/__init__.py +0 -0
  80. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_agentic/config.py +0 -0
  81. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_agentic/generator.py +0 -0
  82. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_agentic/judge.py +0 -0
  83. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_agentic/orchestrator.py +0 -0
  84. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_single_turn/__init__.py +0 -0
  85. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_single_turn/config.py +0 -0
  86. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_single_turn/generator.py +0 -0
  87. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_single_turn/judge.py +0 -0
  88. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/orchestrators/owasp_single_turn/orchestrator.py +0 -0
  89. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/platform_runner.py +0 -0
  90. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/engine/scope.py +0 -0
  91. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/exceptions.py +0 -0
  92. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/extractors/__init__.py +0 -0
  93. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/extractors/openapi.py +0 -0
  94. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/extractors/repo.py +0 -0
  95. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/main.py +0 -0
  96. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/py.typed +0 -0
  97. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/pytest_plugin/__init__.py +0 -0
  98. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/pytest_plugin/fixtures.py +0 -0
  99. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/pytest_plugin/report.py +0 -0
  100. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/report_builder.py +0 -0
  101. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/templates/compliance/banking.yaml +0 -0
  102. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/templates/compliance/ecommerce.yaml +0 -0
  103. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/templates/compliance/eu-ai-act.yaml +0 -0
  104. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/templates/compliance/healthcare.yaml +0 -0
  105. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/templates/compliance/insurance.yaml +0 -0
  106. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/templates/compliance/legal.yaml +0 -0
  107. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/templates/logo.svg +0 -0
  108. {humanbound-2.0.2 → humanbound-2.0.3}/humanbound_cli/templates/report_base.html +0 -0
  109. {humanbound-2.0.2 → humanbound-2.0.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: humanbound
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Humanbound — open-source AI agent red-team engine, SDK, and CLI.
5
5
  Author-email: Humanbound <hello@humanbound.ai>
6
6
  Maintainer-email: Demetris Gerogiannis <hello@humanbound.ai>, Kostas Siabanis <hello@humanbound.ai>
@@ -166,8 +166,9 @@ integration, and API reference all live on
166
166
  ## What's shipping in 2.0
167
167
 
168
168
  - **Clean name**: `humanbound` is the new PyPI install. The old
169
- `humanbound-cli` is a transitional stub that will be yanked after
170
- 2026-06-20.
169
+ `humanbound-cli` package is a discontinued transitional stub (final
170
+ release 1.2.2 depends on `humanbound>=2.0.2`); please install
171
+ `humanbound` directly.
171
172
  - **Public SDK namespace** alongside the CLI — use the CLI or drive the
172
173
  engine from Python. Both share the same implementation, so they can't
173
174
  drift.
@@ -194,5 +195,4 @@ open-source — with attribution. See [TRADEMARK.md](./TRADEMARK.md) for the
194
195
  trademark policy. The code is open; the name is not.
195
196
 
196
197
  The sibling project [`humanbound-firewall`](https://github.com/humanbound/humanbound-firewall)
197
- is dual-licensed (AGPL-3.0 + commercial) different product, different
198
- license strategy.
198
+ is also Apache-2.0 same license, different product.
@@ -104,8 +104,9 @@ integration, and API reference all live on
104
104
  ## What's shipping in 2.0
105
105
 
106
106
  - **Clean name**: `humanbound` is the new PyPI install. The old
107
- `humanbound-cli` is a transitional stub that will be yanked after
108
- 2026-06-20.
107
+ `humanbound-cli` package is a discontinued transitional stub (final
108
+ release 1.2.2 depends on `humanbound>=2.0.2`); please install
109
+ `humanbound` directly.
109
110
  - **Public SDK namespace** alongside the CLI — use the CLI or drive the
110
111
  engine from Python. Both share the same implementation, so they can't
111
112
  drift.
@@ -132,5 +133,4 @@ open-source — with attribution. See [TRADEMARK.md](./TRADEMARK.md) for the
132
133
  trademark policy. The code is open; the name is not.
133
134
 
134
135
  The sibling project [`humanbound-firewall`](https://github.com/humanbound/humanbound-firewall)
135
- is dual-licensed (AGPL-3.0 + commercial) different product, different
136
- license strategy.
136
+ is also Apache-2.0 same license, different product.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: humanbound
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Humanbound — open-source AI agent red-team engine, SDK, and CLI.
5
5
  Author-email: Humanbound <hello@humanbound.ai>
6
6
  Maintainer-email: Demetris Gerogiannis <hello@humanbound.ai>, Kostas Siabanis <hello@humanbound.ai>
@@ -166,8 +166,9 @@ integration, and API reference all live on
166
166
  ## What's shipping in 2.0
167
167
 
168
168
  - **Clean name**: `humanbound` is the new PyPI install. The old
169
- `humanbound-cli` is a transitional stub that will be yanked after
170
- 2026-06-20.
169
+ `humanbound-cli` package is a discontinued transitional stub (final
170
+ release 1.2.2 depends on `humanbound>=2.0.2`); please install
171
+ `humanbound` directly.
171
172
  - **Public SDK namespace** alongside the CLI — use the CLI or drive the
172
173
  engine from Python. Both share the same implementation, so they can't
173
174
  drift.
@@ -194,5 +195,4 @@ open-source — with attribution. See [TRADEMARK.md](./TRADEMARK.md) for the
194
195
  trademark policy. The code is open; the name is not.
195
196
 
196
197
  The sibling project [`humanbound-firewall`](https://github.com/humanbound/humanbound-firewall)
197
- is dual-licensed (AGPL-3.0 + commercial) different product, different
198
- license strategy.
198
+ is also Apache-2.0 same license, different product.
@@ -436,11 +436,21 @@ class HumanboundClient:
436
436
  return True
437
437
 
438
438
  def logout(self, silent: bool = False) -> None:
439
- """Clear stored credentials and logout.
439
+ """Revoke the server session (if any) and clear stored credentials.
440
440
 
441
441
  Args:
442
442
  silent: If True, don't print success message (used for cleanup).
443
443
  """
444
+ if self._api_token:
445
+ try:
446
+ requests.get(
447
+ f"{self.base_url}/logout",
448
+ headers={"Authorization": f"Bearer {self._api_token}"},
449
+ timeout=DEFAULT_TIMEOUT,
450
+ )
451
+ except (requests.ConnectionError, requests.Timeout):
452
+ pass
453
+
444
454
  self._auth0_token = None
445
455
  self._api_token = None
446
456
  self._token_expires_at = None
@@ -138,13 +138,6 @@ def run(testing_configuration, logs, test_category=""):
138
138
  posture = {
139
139
  "posture": posture_score,
140
140
  "grade": grade,
141
- "tests": successful,
142
- "defense_rate": round(defense_rate, 4),
143
- "confidence": confidence,
144
- "domain": domain,
145
- "breach_breadth": round(breach_ratio, 4),
146
- "breached": breached,
147
- "defended": defended,
148
141
  }
149
142
 
150
143
  # --- 3. Lightweight insights (no embeddings, no clustering) ---
@@ -53,7 +53,7 @@ class TestResult:
53
53
  testing_level: str = ""
54
54
  stats: dict = field(default_factory=dict) # {pass, fail, total, ...}
55
55
  insights: list = field(default_factory=list) # [{result, category, severity, explanation}]
56
- posture: dict = field(default_factory=dict) # {posture, grade, defense_rate, ...}
56
+ posture: dict = field(default_factory=dict) # {posture, grade, dimensions}
57
57
  exec_t: dict = field(default_factory=dict) # {max_t, min_t, avg_t}
58
58
 
59
59
 
@@ -183,17 +183,11 @@ class PostureDimensions(BaseModel):
183
183
 
184
184
 
185
185
  class ExperimentPosture(BaseModel):
186
- """Experiment-level posture computed from ASR."""
186
+ """Experiment-level posture."""
187
187
 
188
188
  posture: float = 0
189
189
  grade: str = "F"
190
- tests: int = 0
191
- defense_rate: float = 0
192
- confidence: str = "low"
193
- domain: str = "security"
194
- breach_breadth: float = 0
195
- breached: list[str] = []
196
- defended: list[str] = []
190
+ dimensions: PostureDimensions | None = None
197
191
 
198
192
 
199
193
  # ── Experiment Results ─────────────────────────────────────────────────────
@@ -1402,6 +1402,9 @@ def hb_connect(
1402
1402
  if not client.organisation_id:
1403
1403
  return _err(ValueError("No organisation selected. Use hb_set_organisation first."))
1404
1404
 
1405
+ if context and len(context) > 1500:
1406
+ return _err(ValueError(f"Context too long ({len(context)} chars). Maximum is 1,500."))
1407
+
1405
1408
  # -- Parse endpoint config ----------------------------------------
1406
1409
  try:
1407
1410
  bot_config = json.loads(endpoint_config)
@@ -1467,12 +1470,6 @@ def hb_connect(
1467
1470
 
1468
1471
  configuration = {}
1469
1472
  if context:
1470
- if len(context) > 1500:
1471
- return _err(
1472
- ValueError(
1473
- f"Context too long ({len(context)} chars). Maximum is 1,500."
1474
- )
1475
- )
1476
1473
  configuration["context"] = context
1477
1474
 
1478
1475
  import time as _time
@@ -186,7 +186,7 @@ def generate_html_report(experiment, logs):
186
186
  posture_grade = (
187
187
  posture_data.get("grade", _score_to_grade(posture_score)) if posture_data else "F"
188
188
  )
189
- defense_rate = posture_data.get("defense_rate", 0) if posture_data else 0
189
+ defense_rate = (passed / (passed + failed)) if (passed + failed) > 0 else 0
190
190
 
191
191
  # ── Build report body ──────────────────────────────────
192
192
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "humanbound"
7
- version = "2.0.2"
7
+ version = "2.0.3"
8
8
  description = "Humanbound — open-source AI agent red-team engine, SDK, and CLI."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
File without changes
File without changes
File without changes