openbox-langgraph-sdk-python 0.1.0__tar.gz → 0.1.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 (52) hide show
  1. openbox_langgraph_sdk_python-0.1.2/.gitignore +9 -0
  2. openbox_langgraph_sdk_python-0.1.2/AGENTS.md +91 -0
  3. openbox_langgraph_sdk_python-0.1.2/CLAUDE.md +91 -0
  4. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/PKG-INFO +195 -99
  5. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/README.md +193 -97
  6. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/docs/code-standards.md +5 -5
  7. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/docs/codebase-summary.md +16 -16
  8. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/docs/project-overview-pdr.md +7 -7
  9. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/docs/project-roadmap.md +4 -4
  10. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/docs/system-architecture.md +8 -8
  11. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/config.py +4 -1
  12. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/file_governance_hooks.py +7 -1
  13. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/http_governance_hooks.py +32 -4
  14. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/types.py +6 -3
  15. openbox_langgraph_sdk_python-0.1.2/plans/260320-0329-remove-span-collector/plan.md +121 -0
  16. openbox_langgraph_sdk_python-0.1.2/plans/260321-2019-port-deepagent-fixes/phase-01-remove-hitl-gates.md +53 -0
  17. openbox_langgraph_sdk_python-0.1.2/plans/260321-2019-port-deepagent-fixes/phase-02-sqlalchemy-engine.md +46 -0
  18. openbox_langgraph_sdk_python-0.1.2/plans/260321-2019-port-deepagent-fixes/phase-03-hook-hitl-retry.md +80 -0
  19. openbox_langgraph_sdk_python-0.1.2/plans/260321-2019-port-deepagent-fixes/plan.md +42 -0
  20. openbox_langgraph_sdk_python-0.1.2/plans/reports/Explore-260330-1430-comprehensive-sdk-analysis.md +1753 -0
  21. openbox_langgraph_sdk_python-0.1.2/plans/reports/Explore-260330-2300-file-reference.md +215 -0
  22. openbox_langgraph_sdk_python-0.1.2/plans/reports/Explore-260330-2300-integration-guide.md +747 -0
  23. openbox_langgraph_sdk_python-0.1.2/plans/reports/code-reviewer-260323-1101-code-reuse-otel-hooks.md +206 -0
  24. openbox_langgraph_sdk_python-0.1.2/plans/reports/code-reviewer-260323-1101-efficiency-review-otel-http-hook-spans.md +193 -0
  25. openbox_langgraph_sdk_python-0.1.2/plans/reports/code-reviewer-260323-1101-hacky-patterns-review.md +175 -0
  26. openbox_langgraph_sdk_python-0.1.2/plans/reports/docs-manager-260321-2153-initial-documentation.md +363 -0
  27. openbox_langgraph_sdk_python-0.1.2/plans/reports/span-flow-visualization.html +456 -0
  28. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/pyproject.toml +2 -2
  29. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/uv.lock +6 -6
  30. openbox_langgraph_sdk_python-0.1.0/.gitignore +0 -2
  31. openbox_langgraph_sdk_python-0.1.0/test-agent/.env +0 -11
  32. openbox_langgraph_sdk_python-0.1.0/test-agent/.env.example +0 -9
  33. openbox_langgraph_sdk_python-0.1.0/test-agent/README.md +0 -27
  34. openbox_langgraph_sdk_python-0.1.0/test-agent/SETUP.md +0 -455
  35. openbox_langgraph_sdk_python-0.1.0/test-agent/agent.py +0 -172
  36. openbox_langgraph_sdk_python-0.1.0/test-agent/pyproject.toml +0 -16
  37. openbox_langgraph_sdk_python-0.1.0/test-agent/uv.lock +0 -1218
  38. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/.github/workflows/publish.yml +0 -0
  39. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/__init__.py +0 -0
  40. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/client.py +0 -0
  41. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/db_governance_hooks.py +0 -0
  42. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/errors.py +0 -0
  43. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/hitl.py +0 -0
  44. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/hook_governance.py +0 -0
  45. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/langgraph_handler.py +0 -0
  46. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/otel_setup.py +0 -0
  47. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/span_processor.py +0 -0
  48. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/tracing.py +0 -0
  49. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/openbox_langgraph/verdict_handler.py +0 -0
  50. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/tests/test_contextvars_propagation.py +0 -0
  51. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/tests/test_governance_changes.py +0 -0
  52. {openbox_langgraph_sdk_python-0.1.0 → openbox_langgraph_sdk_python-0.1.2}/tests/test_telemetry_payload.py +0 -0
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .env
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .idea/
8
+ .DS_Store
9
+ repomix-output.xml
@@ -0,0 +1,91 @@
1
+ # AGENTS.md
2
+
3
+ This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
4
+
5
+ ## What This Is
6
+
7
+ Python SDK (`openbox-langgraph-sdk`) that adds real-time governance to LangGraph agents via OpenBox. It intercepts LangGraph v2 stream events (tool calls, LLM prompts, chain executions), sends them to OpenBox Core's policy engine, and enforces verdicts (ALLOW/BLOCK/CONSTRAIN/REQUIRE_APPROVAL/HALT) — all without modifying agent code.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ uv sync
14
+
15
+ # Run all tests
16
+ pytest
17
+
18
+ # Run single test file / pattern
19
+ pytest tests/test_governance_changes.py
20
+ pytest -k "test_httpx"
21
+
22
+ # Lint & format
23
+ ruff check openbox_langgraph/
24
+ ruff format openbox_langgraph/
25
+
26
+ # Type check
27
+ mypy openbox_langgraph/
28
+
29
+ # Debug mode (verbose governance request/response logging)
30
+ OPENBOX_DEBUG=1 pytest -xvs
31
+
32
+ # Run test agent (requires .env with OPENBOX_URL, OPENBOX_API_KEY, OPENAI_API_KEY)
33
+ cd test-agent && uv run python agent.py
34
+ ```
35
+
36
+ ## Architecture
37
+
38
+ The SDK has three governance layers that intercept operations at different levels:
39
+
40
+ ### Layer 1: LangGraph Event Stream (langgraph_handler.py)
41
+ `OpenBoxLangGraphHandler` wraps a compiled LangGraph graph. It processes the v2 event stream (`on_chain_start/end`, `on_tool_start/end`, `on_chat_model_start/end`), sends governance events to OpenBox Core via `GovernanceClient`, and enforces verdicts. This is the main entry point — users call `create_openbox_graph_handler()` (sync function, returns handler immediately) to wrap their graph.
42
+
43
+ ### Layer 2: Hook Governance (http/db/file_governance_hooks.py)
44
+ Intercepts low-level operations using built-in instrumentation:
45
+ - **HTTP** (`http_governance_hooks.py`): httpx request/response hooks with started/completed stages
46
+ - **Database** (`db_governance_hooks.py`): SQLAlchemy event hooks for query classification
47
+ - **File I/O** (`file_governance_hooks.py`): Monkey-patches `os.fdopen()` for file operation tracking
48
+
49
+ Each hook module creates spans and calls `hook_governance.py` → `evaluate_event()` to get verdicts. `hook_governance.py` is the bridge that resolves the current activity context from the SpanProcessor and calls `GovernanceClient`.
50
+
51
+ ### Layer 3: Activity Context (span_processor.py + otel_setup.py)
52
+ `WorkflowSpanProcessor` is a custom SpanProcessor that maps `trace_id` → governance `activity_id`. This lets hook-level governance (Layer 2) find which governance activity a given HTTP/DB/file operation belongs to. `otel_setup.py` initializes all instrumentation and registers the span processor.
53
+
54
+ ### Supporting Modules
55
+ - **client.py**: Async HTTP client (`GovernanceClient`) for OpenBox Core API with dedup and connection pooling
56
+ - **types.py**: Verdict enum, event types, response parsing, utility functions
57
+ - **config.py**: `GovernanceConfig` dataclass, env var parsing, global config registry
58
+ - **verdict_handler.py**: Verdict enforcement logic (block/halt/redact)
59
+ - **hitl.py**: Human-in-the-loop approval polling loop
60
+ - **errors.py**: Exception hierarchy rooted at `OpenBoxError`
61
+ - **tracing.py**: `@traced` decorator and `create_span()` for manual span creation
62
+
63
+ ### Data Flow
64
+ ```
65
+ User calls governed.ainvoke()
66
+ → OpenBoxLangGraphHandler streams LangGraph events
67
+ → GovernanceClient sends event to OpenBox Core
68
+ → Verdict received → enforce_verdict()
69
+ → Meanwhile, hooks intercept HTTP/DB/file ops
70
+ → hook_governance.evaluate_event() with activity context from SpanProcessor
71
+ → Additional verdicts enforced at operation level
72
+ ```
73
+
74
+ ## Tests
75
+
76
+ Three test files in `tests/`:
77
+ - `test_governance_changes.py` — core governance flow (event stream, verdicts, HITL, guardrails)
78
+ - `test_telemetry_payload.py` — hook payload structure and content
79
+ - `test_contextvars_propagation.py` — context variable propagation across async boundaries
80
+
81
+ Tests mock the OpenBox Core API; no live server needed. `pytest-asyncio` with `asyncio_mode = "auto"` means no `@pytest.mark.asyncio` decorator needed.
82
+
83
+ ## Key Conventions
84
+
85
+ - **Python 3.11+**, async-first with sync fallbacks
86
+ - **Package manager**: `uv` (lockfile: `uv.lock`)
87
+ - **Build**: hatchling
88
+ - **Ruff config**: 100 char line length, rules: E/F/I/UP/B/C4/PIE/RUF
89
+ - **mypy**: strict mode
90
+ - Public API exported from `openbox_langgraph/__init__.py`
91
+ - The `test-agent/` directory is a standalone example agent for end-to-end validation, not part of the SDK package
@@ -0,0 +1,91 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## What This Is
6
+
7
+ Python SDK (`openbox-langgraph-sdk`) that adds real-time governance to LangGraph agents via OpenBox. It intercepts LangGraph v2 stream events (tool calls, LLM prompts, chain executions), sends them to OpenBox Core's policy engine, and enforces verdicts (ALLOW/BLOCK/CONSTRAIN/REQUIRE_APPROVAL/HALT) — all without modifying agent code.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ uv sync
14
+
15
+ # Run all tests
16
+ pytest
17
+
18
+ # Run single test file / pattern
19
+ pytest tests/test_governance_changes.py
20
+ pytest -k "test_httpx"
21
+
22
+ # Lint & format
23
+ ruff check openbox_langgraph/
24
+ ruff format openbox_langgraph/
25
+
26
+ # Type check
27
+ mypy openbox_langgraph/
28
+
29
+ # Debug mode (verbose governance request/response logging)
30
+ OPENBOX_DEBUG=1 pytest -xvs
31
+
32
+ # Run test agent (requires .env with OPENBOX_URL, OPENBOX_API_KEY, OPENAI_API_KEY)
33
+ cd test-agent && uv run python agent.py
34
+ ```
35
+
36
+ ## Architecture
37
+
38
+ The SDK has three governance layers that intercept operations at different levels:
39
+
40
+ ### Layer 1: LangGraph Event Stream (langgraph_handler.py)
41
+ `OpenBoxLangGraphHandler` wraps a compiled LangGraph graph. It processes the v2 event stream (`on_chain_start/end`, `on_tool_start/end`, `on_chat_model_start/end`), sends governance events to OpenBox Core via `GovernanceClient`, and enforces verdicts. This is the main entry point — users call `create_openbox_graph_handler()` (sync function, returns handler immediately) to wrap their graph.
42
+
43
+ ### Layer 2: Hook Governance (http/db/file_governance_hooks.py)
44
+ Intercepts low-level operations using built-in instrumentation:
45
+ - **HTTP** (`http_governance_hooks.py`): httpx request/response hooks with started/completed stages
46
+ - **Database** (`db_governance_hooks.py`): SQLAlchemy event hooks for query classification
47
+ - **File I/O** (`file_governance_hooks.py`): Monkey-patches `os.fdopen()` for file operation tracking
48
+
49
+ Each hook module creates spans and calls `hook_governance.py` → `evaluate_event()` to get verdicts. `hook_governance.py` is the bridge that resolves the current activity context from the SpanProcessor and calls `GovernanceClient`.
50
+
51
+ ### Layer 3: Activity Context (span_processor.py + otel_setup.py)
52
+ `WorkflowSpanProcessor` is a custom SpanProcessor that maps `trace_id` → governance `activity_id`. This lets hook-level governance (Layer 2) find which governance activity a given HTTP/DB/file operation belongs to. `otel_setup.py` initializes all instrumentation and registers the span processor.
53
+
54
+ ### Supporting Modules
55
+ - **client.py**: Async HTTP client (`GovernanceClient`) for OpenBox Core API with dedup and connection pooling
56
+ - **types.py**: Verdict enum, event types, response parsing, utility functions
57
+ - **config.py**: `GovernanceConfig` dataclass, env var parsing, global config registry
58
+ - **verdict_handler.py**: Verdict enforcement logic (block/halt/redact)
59
+ - **hitl.py**: Human-in-the-loop approval polling loop
60
+ - **errors.py**: Exception hierarchy rooted at `OpenBoxError`
61
+ - **tracing.py**: `@traced` decorator and `create_span()` for manual span creation
62
+
63
+ ### Data Flow
64
+ ```
65
+ User calls governed.ainvoke()
66
+ → OpenBoxLangGraphHandler streams LangGraph events
67
+ → GovernanceClient sends event to OpenBox Core
68
+ → Verdict received → enforce_verdict()
69
+ → Meanwhile, hooks intercept HTTP/DB/file ops
70
+ → hook_governance.evaluate_event() with activity context from SpanProcessor
71
+ → Additional verdicts enforced at operation level
72
+ ```
73
+
74
+ ## Tests
75
+
76
+ Three test files in `tests/`:
77
+ - `test_governance_changes.py` — core governance flow (event stream, verdicts, HITL, guardrails)
78
+ - `test_telemetry_payload.py` — hook payload structure and content
79
+ - `test_contextvars_propagation.py` — context variable propagation across async boundaries
80
+
81
+ Tests mock the OpenBox Core API; no live server needed. `pytest-asyncio` with `asyncio_mode = "auto"` means no `@pytest.mark.asyncio` decorator needed.
82
+
83
+ ## Key Conventions
84
+
85
+ - **Python 3.11+**, async-first with sync fallbacks
86
+ - **Package manager**: `uv` (lockfile: `uv.lock`)
87
+ - **Build**: hatchling
88
+ - **Ruff config**: 100 char line length, rules: E/F/I/UP/B/C4/PIE/RUF
89
+ - **mypy**: strict mode
90
+ - Public API exported from `openbox_langgraph/__init__.py`
91
+ - The `test-agent/` directory is a standalone example agent for end-to-end validation, not part of the SDK package