hexgate 0.2.1__tar.gz → 0.2.2__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 (107) hide show
  1. hexgate-0.2.2/LICENSE +21 -0
  2. {hexgate-0.2.1 → hexgate-0.2.2}/PKG-INFO +74 -39
  3. {hexgate-0.2.1 → hexgate-0.2.2}/README.md +70 -38
  4. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/google/runner.py +18 -2
  5. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/openai/runner.py +10 -9
  6. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate.egg-info/PKG-INFO +74 -39
  7. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate.egg-info/SOURCES.txt +1 -0
  8. {hexgate-0.2.1 → hexgate-0.2.2}/pyproject.toml +3 -1
  9. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/__init__.py +0 -0
  10. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/__init__.py +0 -0
  11. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/google/__init__.py +0 -0
  12. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/google/tools.py +0 -0
  13. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/google/wrapper.py +0 -0
  14. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/langchain/__init__.py +0 -0
  15. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/langchain/agent.py +0 -0
  16. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/langchain/tools.py +0 -0
  17. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/langchain/wrapper.py +0 -0
  18. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/openai/__init__.py +0 -0
  19. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/openai/tools.py +0 -0
  20. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/openai/wrapper.py +0 -0
  21. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/pydantic_ai/__init__.py +0 -0
  22. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/pydantic_ai/agent.py +0 -0
  23. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/pydantic_ai/tools.py +0 -0
  24. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/adapters/pydantic_ai/wrapper.py +0 -0
  25. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/__init__.py +0 -0
  26. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/builtin/__init__.py +0 -0
  27. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/builtin/researcher/agent.yaml +0 -0
  28. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/builtin/researcher/policy.yaml +0 -0
  29. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/builtin/researcher/system.md +0 -0
  30. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/factory.py +0 -0
  31. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/loader.py +0 -0
  32. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/models.py +0 -0
  33. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/agents/prompts/agent_system.md +0 -0
  34. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/audit.py +0 -0
  35. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/bootstrap.py +0 -0
  36. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/__init__.py +0 -0
  37. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/_common.py +0 -0
  38. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/chat.py +0 -0
  39. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/policy/__init__.py +0 -0
  40. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/policy/main.py +0 -0
  41. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/__init__.py +0 -0
  42. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/google.py +0 -0
  43. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/hexgate.py +0 -0
  44. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/langchain.py +0 -0
  45. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/main.py +0 -0
  46. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/manifest.py +0 -0
  47. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/models.py +0 -0
  48. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/openai.py +0 -0
  49. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/pydantic_ai.py +0 -0
  50. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/register/register.py +0 -0
  51. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/serve.py +0 -0
  52. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cli/state.py +0 -0
  53. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cloud/__init__.py +0 -0
  54. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cloud/attenuate.py +0 -0
  55. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cloud/biscuit.py +0 -0
  56. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/cloud/client.py +0 -0
  57. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/config/__init__.py +0 -0
  58. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/config/settings.py +0 -0
  59. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/runtime/__init__.py +0 -0
  60. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/runtime/command_policy.py +0 -0
  61. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/runtime/context.py +0 -0
  62. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/runtime/sandbox_runtime.py +0 -0
  63. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/runtime/srt.py +0 -0
  64. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/runtime/workspace.py +0 -0
  65. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/__init__.py +0 -0
  66. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/binding.py +0 -0
  67. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/bundle.py +0 -0
  68. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/constraints.py +0 -0
  69. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/decision.py +0 -0
  70. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/enforcer.py +0 -0
  71. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/errors.py +0 -0
  72. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/file_scope.py +0 -0
  73. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/models.py +0 -0
  74. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/policy.py +0 -0
  75. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/policy_set.py +0 -0
  76. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/rego.py +0 -0
  77. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/rego_wasm.py +0 -0
  78. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/signing.py +0 -0
  79. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/source.py +0 -0
  80. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/security/wasm_engine.py +0 -0
  81. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/streaming/__init__.py +0 -0
  82. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/streaming/events.py +0 -0
  83. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/streaming/normalize.py +0 -0
  84. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/__init__.py +0 -0
  85. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/bash.py +0 -0
  86. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/decorators.py +0 -0
  87. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/fetch.py +0 -0
  88. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/files/__init__.py +0 -0
  89. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/files/_common.py +0 -0
  90. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/files/edit_file.py +0 -0
  91. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/files/glob.py +0 -0
  92. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/files/grep.py +0 -0
  93. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/files/read_file.py +0 -0
  94. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/files/write_file.py +0 -0
  95. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/refund.py +0 -0
  96. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tools/websearch.py +0 -0
  97. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tracing/__init__.py +0 -0
  98. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/tracing/langfuse.py +0 -0
  99. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/utils/__init__.py +0 -0
  100. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate/utils/retry.py +0 -0
  101. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate.egg-info/dependency_links.txt +0 -0
  102. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate.egg-info/entry_points.txt +0 -0
  103. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate.egg-info/requires.txt +0 -0
  104. {hexgate-0.2.1 → hexgate-0.2.2}/hexgate.egg-info/top_level.txt +0 -0
  105. {hexgate-0.2.1 → hexgate-0.2.2}/setup.cfg +0 -0
  106. {hexgate-0.2.1 → hexgate-0.2.2}/tests/test_bootstrap.py +0 -0
  107. {hexgate-0.2.1 → hexgate-0.2.2}/tests/test_demo.py +0 -0
hexgate-0.2.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hexamind
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,9 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hexgate
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: HexaGate — authorization infrastructure for AI agents (agent runtime + cloud client).
5
+ License-Expression: MIT
5
6
  Requires-Python: >=3.13
6
7
  Description-Content-Type: text/markdown
8
+ License-File: LICENSE
7
9
  Requires-Dist: bashlex>=0.18
8
10
  Requires-Dist: biscuit-python>=0.4
9
11
  Requires-Dist: cryptography>=42
@@ -33,21 +35,77 @@ Requires-Dist: jupyter; extra == "dev"
33
35
  Requires-Dist: pytest>=8.4.1; extra == "dev"
34
36
  Requires-Dist: pytest-asyncio>=1.0.0; extra == "dev"
35
37
  Requires-Dist: ruff>=0.12.2; extra == "dev"
38
+ Dynamic: license-file
36
39
 
37
- # hexgate
40
+ <div align="center">
38
41
 
39
- `hexgate` is a lightweight LangChain-based agent runtime built around:
42
+ # HexaGate
40
43
 
41
- - `langchain`
42
- - `gpt-5.4`
43
- - `Linkup` web search
44
- - Tavily-based page fetch
45
- - `Langfuse` tracing
44
+ **Authorization infrastructure for AI agents.**
45
+ Policy enforcement, signed policy bundles, per-request user scope, audit trail — for OpenAI Agents, LangChain, Google ADK, Pydantic AI, or a native runtime.
46
46
 
47
- This package is intentionally small. The first milestone is a single assistant with:
47
+ [![PyPI](https://img.shields.io/pypi/v/hexgate?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/hexgate/)
48
+ [![Python](https://img.shields.io/pypi/pyversions/hexgate?logo=python&logoColor=white)](https://pypi.org/project/hexgate/)
49
+ [![CI](https://github.com/HexamindOrganisation/hexgate/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/HexamindOrganisation/hexgate/actions/workflows/tests.yml)
50
+ [![Downloads](https://img.shields.io/pypi/dm/hexgate?color=blueviolet)](https://pypi.org/project/hexgate/)
51
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
48
52
 
49
- - `web_search`
50
- - `fetch`
53
+ [Quick Start](#-quick-start--local-cli) · [Two paths](#-which-path-do-i-pick) · [Framework adapters](#-framework-agent-wrapping) · [Policy bundles](#-policy-bundles--compile-sign-enforce-wasm) · [User scope](#-user-scope--roles) · [Platform](#-hexagate-platform)
54
+
55
+ </div>
56
+
57
+ ---
58
+
59
+ ## What is HexaGate?
60
+
61
+ HexaGate is two things that move together:
62
+
63
+ - **`hexgate` — the SDK.** A Python runtime that gates every tool call through a typed `Decision` (allow / deny / approval-required), wraps your existing OpenAI / LangChain / Google ADK / Pydantic AI agent without rewriting it, and threads per-request user identity through tracing + audit.
64
+ - **The HexaGate platform** *(optional)* — a FastAPI control plane + React dashboard for editing policy in a browser, minting per-project tokens, watching live decisions stream from a serving agent, and shipping signed WASM policy bundles to production.
65
+
66
+ You can use the SDK with nothing else (single-process REPL, YAML on disk). Or plug in the platform when you want auditable decisions in ClickHouse, a shared Playground UI, and live policy edits.
67
+
68
+ ```text
69
+ ┌─────────────────────────────────────────┐
70
+ your code ───► │ create_agent / wrap_*_agent / Runner │
71
+ │ ↓ │
72
+ │ PolicyEnforcer.decide(role, tool) │
73
+ │ ↓ │
74
+ │ allow · deny · approval_required │
75
+ └────────────────────┬────────────────────┘
76
+
77
+ ┌────────────────────────┼─────────────────────────┐
78
+ ▼ ▼ ▼
79
+ ┌────────────────┐ ┌──────────────────┐ ┌────────────────┐
80
+ │ Local policy │ │ Signed WASM │ │ Audit log │
81
+ │ (YAML / dir, │ │ bundle from │ │ (ClickHouse │
82
+ │ hot reload) │ │ HexaGate cloud │ │ via REST) │
83
+ └────────────────┘ └──────────────────┘ └────────────────┘
84
+ ```
85
+
86
+ ## Table of contents
87
+
88
+ - [Prerequisites](#-prerequisites)
89
+ - [Quick Start — Local CLI](#-quick-start--local-cli)
90
+ - [Which path do I pick?](#-which-path-do-i-pick) — chat vs serve
91
+ - [Quick Start — Platform](#-quick-start--platform)
92
+ - [Core primitives](#-core-primitives)
93
+ - [Build an agent — end to end](#-build-an-agent--end-to-end)
94
+ - [What you can import](#-what-you-can-import)
95
+ - [Framework agent wrapping](#-framework-agent-wrapping) — OpenAI, LangChain, Google ADK, Pydantic AI
96
+ - [Define agents in code](#-define-agents-in-code)
97
+ - [Builtin and local agents](#-builtin-and-local-agents)
98
+ - [Policy shape](#-policy-shape)
99
+ - [Tool-call policy enforcement](#-tool-call-policy-enforcement)
100
+ - [Policy bundles — compile, sign, enforce (WASM)](#-policy-bundles--compile-sign-enforce-wasm)
101
+ - [Approval-required tool calls](#-approval-required-tool-calls)
102
+ - [Workspace sandbox](#-workspace-sandbox)
103
+ - [Environment](#-environment)
104
+ - [Tests & dev tooling](#-tests--dev-tooling)
105
+ - [CLI reference](#-cli-reference)
106
+ - [HexaGate platform](#-hexagate-platform)
107
+ - [User scope + roles](#-user-scope--roles)
108
+ - [Stream results](#-stream-results)
51
109
 
52
110
  ## 🛠️ Prerequisites
53
111
 
@@ -1059,41 +1117,18 @@ The platform-side test suite is separate and lives at `platform/api/tests/`:
1059
1117
  cd platform/api && uv run pytest tests/
1060
1118
  ```
1061
1119
 
1062
- ## ▶️ Run It
1063
-
1064
- Install the package into your current environment:
1065
-
1066
- ```bash
1067
- python -m pip install -e .
1068
- ```
1120
+ ## 🖥️ CLI reference
1069
1121
 
1070
- Run the config-driven demo:
1071
-
1072
- ```bash
1073
- python examples/demo.py
1074
- ```
1075
-
1076
- Run the inline chat CLI with a local or builtin YAML agent:
1077
-
1078
- ```bash
1079
- hexgate chat --agent example_agent
1080
- ```
1081
-
1082
- Run the CLI with code-defined agents from a Python script:
1122
+ The `hexgate` binary exposes `chat`, `serve`, `register`, and `policy` subcommands. The [Quick Start](#-quick-start--local-cli) covers `chat`; this section drills into `register` and `serve` for the platform path.
1083
1123
 
1084
1124
  ```bash
1125
+ hexgate --help # list subcommands
1126
+ hexgate <subcommand> --help # flags for a subcommand
1127
+ hexgate chat --list-agents # show resolvable agents
1085
1128
  hexgate chat --use examples/file_agents.py --agent workspace_explorer
1086
- hexgate chat --use examples/file_agents.py --agent repo_editor
1087
- hexgate chat --use examples/research_agents.py --agent update_researcher
1088
1129
  hexgate chat --use examples/research_agents.py --agent update_researcher --approval-mode ask
1089
1130
  ```
1090
1131
 
1091
- List what the CLI can currently resolve:
1092
-
1093
- ```bash
1094
- hexgate chat --list-agents
1095
- ```
1096
-
1097
1132
  ### `hexgate register` — push a manifest to the platform
1098
1133
 
1099
1134
  Register a code-defined agent's manifest with the HexaGate platform. `--agent`
@@ -1,17 +1,72 @@
1
- # hexgate
1
+ <div align="center">
2
2
 
3
- `hexgate` is a lightweight LangChain-based agent runtime built around:
3
+ # HexaGate
4
4
 
5
- - `langchain`
6
- - `gpt-5.4`
7
- - `Linkup` web search
8
- - Tavily-based page fetch
9
- - `Langfuse` tracing
5
+ **Authorization infrastructure for AI agents.**
6
+ Policy enforcement, signed policy bundles, per-request user scope, audit trail — for OpenAI Agents, LangChain, Google ADK, Pydantic AI, or a native runtime.
10
7
 
11
- This package is intentionally small. The first milestone is a single assistant with:
8
+ [![PyPI](https://img.shields.io/pypi/v/hexgate?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/hexgate/)
9
+ [![Python](https://img.shields.io/pypi/pyversions/hexgate?logo=python&logoColor=white)](https://pypi.org/project/hexgate/)
10
+ [![CI](https://github.com/HexamindOrganisation/hexgate/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/HexamindOrganisation/hexgate/actions/workflows/tests.yml)
11
+ [![Downloads](https://img.shields.io/pypi/dm/hexgate?color=blueviolet)](https://pypi.org/project/hexgate/)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
12
13
 
13
- - `web_search`
14
- - `fetch`
14
+ [Quick Start](#-quick-start--local-cli) · [Two paths](#-which-path-do-i-pick) · [Framework adapters](#-framework-agent-wrapping) · [Policy bundles](#-policy-bundles--compile-sign-enforce-wasm) · [User scope](#-user-scope--roles) · [Platform](#-hexagate-platform)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## What is HexaGate?
21
+
22
+ HexaGate is two things that move together:
23
+
24
+ - **`hexgate` — the SDK.** A Python runtime that gates every tool call through a typed `Decision` (allow / deny / approval-required), wraps your existing OpenAI / LangChain / Google ADK / Pydantic AI agent without rewriting it, and threads per-request user identity through tracing + audit.
25
+ - **The HexaGate platform** *(optional)* — a FastAPI control plane + React dashboard for editing policy in a browser, minting per-project tokens, watching live decisions stream from a serving agent, and shipping signed WASM policy bundles to production.
26
+
27
+ You can use the SDK with nothing else (single-process REPL, YAML on disk). Or plug in the platform when you want auditable decisions in ClickHouse, a shared Playground UI, and live policy edits.
28
+
29
+ ```text
30
+ ┌─────────────────────────────────────────┐
31
+ your code ───► │ create_agent / wrap_*_agent / Runner │
32
+ │ ↓ │
33
+ │ PolicyEnforcer.decide(role, tool) │
34
+ │ ↓ │
35
+ │ allow · deny · approval_required │
36
+ └────────────────────┬────────────────────┘
37
+
38
+ ┌────────────────────────┼─────────────────────────┐
39
+ ▼ ▼ ▼
40
+ ┌────────────────┐ ┌──────────────────┐ ┌────────────────┐
41
+ │ Local policy │ │ Signed WASM │ │ Audit log │
42
+ │ (YAML / dir, │ │ bundle from │ │ (ClickHouse │
43
+ │ hot reload) │ │ HexaGate cloud │ │ via REST) │
44
+ └────────────────┘ └──────────────────┘ └────────────────┘
45
+ ```
46
+
47
+ ## Table of contents
48
+
49
+ - [Prerequisites](#-prerequisites)
50
+ - [Quick Start — Local CLI](#-quick-start--local-cli)
51
+ - [Which path do I pick?](#-which-path-do-i-pick) — chat vs serve
52
+ - [Quick Start — Platform](#-quick-start--platform)
53
+ - [Core primitives](#-core-primitives)
54
+ - [Build an agent — end to end](#-build-an-agent--end-to-end)
55
+ - [What you can import](#-what-you-can-import)
56
+ - [Framework agent wrapping](#-framework-agent-wrapping) — OpenAI, LangChain, Google ADK, Pydantic AI
57
+ - [Define agents in code](#-define-agents-in-code)
58
+ - [Builtin and local agents](#-builtin-and-local-agents)
59
+ - [Policy shape](#-policy-shape)
60
+ - [Tool-call policy enforcement](#-tool-call-policy-enforcement)
61
+ - [Policy bundles — compile, sign, enforce (WASM)](#-policy-bundles--compile-sign-enforce-wasm)
62
+ - [Approval-required tool calls](#-approval-required-tool-calls)
63
+ - [Workspace sandbox](#-workspace-sandbox)
64
+ - [Environment](#-environment)
65
+ - [Tests & dev tooling](#-tests--dev-tooling)
66
+ - [CLI reference](#-cli-reference)
67
+ - [HexaGate platform](#-hexagate-platform)
68
+ - [User scope + roles](#-user-scope--roles)
69
+ - [Stream results](#-stream-results)
15
70
 
16
71
  ## 🛠️ Prerequisites
17
72
 
@@ -1023,41 +1078,18 @@ The platform-side test suite is separate and lives at `platform/api/tests/`:
1023
1078
  cd platform/api && uv run pytest tests/
1024
1079
  ```
1025
1080
 
1026
- ## ▶️ Run It
1027
-
1028
- Install the package into your current environment:
1029
-
1030
- ```bash
1031
- python -m pip install -e .
1032
- ```
1081
+ ## 🖥️ CLI reference
1033
1082
 
1034
- Run the config-driven demo:
1035
-
1036
- ```bash
1037
- python examples/demo.py
1038
- ```
1039
-
1040
- Run the inline chat CLI with a local or builtin YAML agent:
1041
-
1042
- ```bash
1043
- hexgate chat --agent example_agent
1044
- ```
1045
-
1046
- Run the CLI with code-defined agents from a Python script:
1083
+ The `hexgate` binary exposes `chat`, `serve`, `register`, and `policy` subcommands. The [Quick Start](#-quick-start--local-cli) covers `chat`; this section drills into `register` and `serve` for the platform path.
1047
1084
 
1048
1085
  ```bash
1086
+ hexgate --help # list subcommands
1087
+ hexgate <subcommand> --help # flags for a subcommand
1088
+ hexgate chat --list-agents # show resolvable agents
1049
1089
  hexgate chat --use examples/file_agents.py --agent workspace_explorer
1050
- hexgate chat --use examples/file_agents.py --agent repo_editor
1051
- hexgate chat --use examples/research_agents.py --agent update_researcher
1052
1090
  hexgate chat --use examples/research_agents.py --agent update_researcher --approval-mode ask
1053
1091
  ```
1054
1092
 
1055
- List what the CLI can currently resolve:
1056
-
1057
- ```bash
1058
- hexgate chat --list-agents
1059
- ```
1060
-
1061
1093
  ### `hexgate register` — push a manifest to the platform
1062
1094
 
1063
1095
  Register a code-defined agent's manifest with the HexaGate platform. `--agent`
@@ -79,16 +79,32 @@ class HexgateRunner:
79
79
  user: User,
80
80
  **kwargs: Any,
81
81
  ) -> Generator[Any, None, None]:
82
- """Run the Google ADK agent synchronously, yielding events."""
82
+ """Run the Google ADK agent synchronously, yielding events.
83
+
84
+ ADK's ``Runner.run`` drives the agent loop in a worker thread whose
85
+ context cannot see our :class:`User` scope, so the tools' enforcers
86
+ lose the active role. We drive ``run_async`` inline on a per-call loop
87
+ instead, keeping execution in this scoped thread.
88
+ """
83
89
  self._setup_observability()
84
90
  self._binding.refresh() # per-run policy pull; 304 when unchanged
85
91
  with user.sync_scope(), self._propagate(user):
86
- yield from self._runner.run(
92
+ agen = self._runner.run_async(
87
93
  user_id=user.user_id,
88
94
  session_id=user.session_id,
89
95
  new_message=new_message,
90
96
  **kwargs,
91
97
  )
98
+ loop = asyncio.new_event_loop()
99
+ try:
100
+ while True:
101
+ try:
102
+ yield loop.run_until_complete(agen.__anext__())
103
+ except StopAsyncIteration:
104
+ break
105
+ finally:
106
+ loop.run_until_complete(agen.aclose())
107
+ loop.close()
92
108
 
93
109
  async def run_async(
94
110
  self,
@@ -134,21 +134,22 @@ class HexgateRunner:
134
134
  ) -> RunResultStreaming:
135
135
  """Stream the OpenAI agent inside a User scope.
136
136
 
137
- ``Runner.run_streamed`` returns sync; tools only run during
138
- ``stream_events`` iteration. The User scope is opened inside the
139
- wrapped iterator. Langfuse propagation runs during setup so the
140
- trace span attaches. The policy refresh runs in the setup body
141
- the wrap is fixed before tools fire during stream_events.
137
+ ``Runner.run_streamed`` returns sync but spawns the agent loop as a
138
+ background task that snapshots the current contextvars at creation;
139
+ tools fire there, not in ``stream_events``. So the User scope must be
140
+ active around the ``run_streamed`` call for the task to inherit it
141
+ the wrapped iterator re-opens it for exit/audit semantics.
142
142
  """
143
143
  self._setup_observability()
144
144
  binding = self._binding_for(agent)
145
145
  binding.refresh() # must precede the wrap + setup
146
146
  wrapped_agent = wrap_openai_agent(agent, enforcer=binding.enforcer)
147
147
 
148
- with self._propagate(user, agent.name):
149
- result = Runner.run_streamed(
150
- wrapped_agent, input, run_config=run_config, **kwargs
151
- )
148
+ with user.sync_scope():
149
+ with self._propagate(user, agent.name):
150
+ result = Runner.run_streamed(
151
+ wrapped_agent, input, run_config=run_config, **kwargs
152
+ )
152
153
 
153
154
  original_stream_events = result.stream_events
154
155
 
@@ -1,9 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hexgate
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: HexaGate — authorization infrastructure for AI agents (agent runtime + cloud client).
5
+ License-Expression: MIT
5
6
  Requires-Python: >=3.13
6
7
  Description-Content-Type: text/markdown
8
+ License-File: LICENSE
7
9
  Requires-Dist: bashlex>=0.18
8
10
  Requires-Dist: biscuit-python>=0.4
9
11
  Requires-Dist: cryptography>=42
@@ -33,21 +35,77 @@ Requires-Dist: jupyter; extra == "dev"
33
35
  Requires-Dist: pytest>=8.4.1; extra == "dev"
34
36
  Requires-Dist: pytest-asyncio>=1.0.0; extra == "dev"
35
37
  Requires-Dist: ruff>=0.12.2; extra == "dev"
38
+ Dynamic: license-file
36
39
 
37
- # hexgate
40
+ <div align="center">
38
41
 
39
- `hexgate` is a lightweight LangChain-based agent runtime built around:
42
+ # HexaGate
40
43
 
41
- - `langchain`
42
- - `gpt-5.4`
43
- - `Linkup` web search
44
- - Tavily-based page fetch
45
- - `Langfuse` tracing
44
+ **Authorization infrastructure for AI agents.**
45
+ Policy enforcement, signed policy bundles, per-request user scope, audit trail — for OpenAI Agents, LangChain, Google ADK, Pydantic AI, or a native runtime.
46
46
 
47
- This package is intentionally small. The first milestone is a single assistant with:
47
+ [![PyPI](https://img.shields.io/pypi/v/hexgate?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/hexgate/)
48
+ [![Python](https://img.shields.io/pypi/pyversions/hexgate?logo=python&logoColor=white)](https://pypi.org/project/hexgate/)
49
+ [![CI](https://github.com/HexamindOrganisation/hexgate/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/HexamindOrganisation/hexgate/actions/workflows/tests.yml)
50
+ [![Downloads](https://img.shields.io/pypi/dm/hexgate?color=blueviolet)](https://pypi.org/project/hexgate/)
51
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
48
52
 
49
- - `web_search`
50
- - `fetch`
53
+ [Quick Start](#-quick-start--local-cli) · [Two paths](#-which-path-do-i-pick) · [Framework adapters](#-framework-agent-wrapping) · [Policy bundles](#-policy-bundles--compile-sign-enforce-wasm) · [User scope](#-user-scope--roles) · [Platform](#-hexagate-platform)
54
+
55
+ </div>
56
+
57
+ ---
58
+
59
+ ## What is HexaGate?
60
+
61
+ HexaGate is two things that move together:
62
+
63
+ - **`hexgate` — the SDK.** A Python runtime that gates every tool call through a typed `Decision` (allow / deny / approval-required), wraps your existing OpenAI / LangChain / Google ADK / Pydantic AI agent without rewriting it, and threads per-request user identity through tracing + audit.
64
+ - **The HexaGate platform** *(optional)* — a FastAPI control plane + React dashboard for editing policy in a browser, minting per-project tokens, watching live decisions stream from a serving agent, and shipping signed WASM policy bundles to production.
65
+
66
+ You can use the SDK with nothing else (single-process REPL, YAML on disk). Or plug in the platform when you want auditable decisions in ClickHouse, a shared Playground UI, and live policy edits.
67
+
68
+ ```text
69
+ ┌─────────────────────────────────────────┐
70
+ your code ───► │ create_agent / wrap_*_agent / Runner │
71
+ │ ↓ │
72
+ │ PolicyEnforcer.decide(role, tool) │
73
+ │ ↓ │
74
+ │ allow · deny · approval_required │
75
+ └────────────────────┬────────────────────┘
76
+
77
+ ┌────────────────────────┼─────────────────────────┐
78
+ ▼ ▼ ▼
79
+ ┌────────────────┐ ┌──────────────────┐ ┌────────────────┐
80
+ │ Local policy │ │ Signed WASM │ │ Audit log │
81
+ │ (YAML / dir, │ │ bundle from │ │ (ClickHouse │
82
+ │ hot reload) │ │ HexaGate cloud │ │ via REST) │
83
+ └────────────────┘ └──────────────────┘ └────────────────┘
84
+ ```
85
+
86
+ ## Table of contents
87
+
88
+ - [Prerequisites](#-prerequisites)
89
+ - [Quick Start — Local CLI](#-quick-start--local-cli)
90
+ - [Which path do I pick?](#-which-path-do-i-pick) — chat vs serve
91
+ - [Quick Start — Platform](#-quick-start--platform)
92
+ - [Core primitives](#-core-primitives)
93
+ - [Build an agent — end to end](#-build-an-agent--end-to-end)
94
+ - [What you can import](#-what-you-can-import)
95
+ - [Framework agent wrapping](#-framework-agent-wrapping) — OpenAI, LangChain, Google ADK, Pydantic AI
96
+ - [Define agents in code](#-define-agents-in-code)
97
+ - [Builtin and local agents](#-builtin-and-local-agents)
98
+ - [Policy shape](#-policy-shape)
99
+ - [Tool-call policy enforcement](#-tool-call-policy-enforcement)
100
+ - [Policy bundles — compile, sign, enforce (WASM)](#-policy-bundles--compile-sign-enforce-wasm)
101
+ - [Approval-required tool calls](#-approval-required-tool-calls)
102
+ - [Workspace sandbox](#-workspace-sandbox)
103
+ - [Environment](#-environment)
104
+ - [Tests & dev tooling](#-tests--dev-tooling)
105
+ - [CLI reference](#-cli-reference)
106
+ - [HexaGate platform](#-hexagate-platform)
107
+ - [User scope + roles](#-user-scope--roles)
108
+ - [Stream results](#-stream-results)
51
109
 
52
110
  ## 🛠️ Prerequisites
53
111
 
@@ -1059,41 +1117,18 @@ The platform-side test suite is separate and lives at `platform/api/tests/`:
1059
1117
  cd platform/api && uv run pytest tests/
1060
1118
  ```
1061
1119
 
1062
- ## ▶️ Run It
1063
-
1064
- Install the package into your current environment:
1065
-
1066
- ```bash
1067
- python -m pip install -e .
1068
- ```
1120
+ ## 🖥️ CLI reference
1069
1121
 
1070
- Run the config-driven demo:
1071
-
1072
- ```bash
1073
- python examples/demo.py
1074
- ```
1075
-
1076
- Run the inline chat CLI with a local or builtin YAML agent:
1077
-
1078
- ```bash
1079
- hexgate chat --agent example_agent
1080
- ```
1081
-
1082
- Run the CLI with code-defined agents from a Python script:
1122
+ The `hexgate` binary exposes `chat`, `serve`, `register`, and `policy` subcommands. The [Quick Start](#-quick-start--local-cli) covers `chat`; this section drills into `register` and `serve` for the platform path.
1083
1123
 
1084
1124
  ```bash
1125
+ hexgate --help # list subcommands
1126
+ hexgate <subcommand> --help # flags for a subcommand
1127
+ hexgate chat --list-agents # show resolvable agents
1085
1128
  hexgate chat --use examples/file_agents.py --agent workspace_explorer
1086
- hexgate chat --use examples/file_agents.py --agent repo_editor
1087
- hexgate chat --use examples/research_agents.py --agent update_researcher
1088
1129
  hexgate chat --use examples/research_agents.py --agent update_researcher --approval-mode ask
1089
1130
  ```
1090
1131
 
1091
- List what the CLI can currently resolve:
1092
-
1093
- ```bash
1094
- hexgate chat --list-agents
1095
- ```
1096
-
1097
1132
  ### `hexgate register` — push a manifest to the platform
1098
1133
 
1099
1134
  Register a code-defined agent's manifest with the HexaGate platform. `--agent`
@@ -1,3 +1,4 @@
1
+ LICENSE
1
2
  README.md
2
3
  pyproject.toml
3
4
  hexgate/__init__.py
@@ -9,9 +9,11 @@ build-backend = "setuptools.build_meta"
9
9
  # 0.2.0 (the original package name was taken on PyPI by a 2014
10
10
  # abandoned project; the team consolidated on `hexgate` for everything).
11
11
  name = "hexgate"
12
- version = "0.2.1"
12
+ version = "0.2.2"
13
13
  description = "HexaGate — authorization infrastructure for AI agents (agent runtime + cloud client)."
14
14
  readme = "README.md"
15
+ license = "MIT"
16
+ license-files = ["LICENSE"]
15
17
  requires-python = ">=3.13"
16
18
  dependencies = [
17
19
  "bashlex>=0.18",
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes