agent-harness-bridge 0.1.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 chansigit
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.
@@ -0,0 +1,154 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-harness-bridge
3
+ Version: 0.1.0
4
+ Summary: A small compatibility layer for OpenAI Agents SDK, Claude Agent SDK, and DeepSeek Harness
5
+ Author-email: chansigit <chansigit@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 chansigit
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/chansigit/agent-harness-bridge
29
+ Project-URL: Repository, https://github.com/chansigit/agent-harness-bridge
30
+ Project-URL: Issues, https://github.com/chansigit/agent-harness-bridge/issues
31
+ Classifier: Programming Language :: Python :: 3
32
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
33
+ Requires-Python: >=3.10
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Provides-Extra: openai
37
+ Requires-Dist: openai-agents==0.22.0; extra == "openai"
38
+ Provides-Extra: claude
39
+ Requires-Dist: claude-agent-sdk>=0.2.152; extra == "claude"
40
+ Provides-Extra: deepseek
41
+ Requires-Dist: mcp<2,>=1.19; extra == "deepseek"
42
+ Requires-Dist: PyYAML>=6; extra == "deepseek"
43
+ Requires-Dist: uvicorn>=0.30; extra == "deepseek"
44
+ Requires-Dist: sse-starlette<4,>=3; extra == "deepseek"
45
+ Provides-Extra: all
46
+ Requires-Dist: openai-agents==0.22.0; extra == "all"
47
+ Requires-Dist: claude-agent-sdk>=0.2.152; extra == "all"
48
+ Requires-Dist: mcp<2,>=1.19; extra == "all"
49
+ Requires-Dist: PyYAML>=6; extra == "all"
50
+ Requires-Dist: uvicorn>=0.30; extra == "all"
51
+ Requires-Dist: sse-starlette<4,>=3; extra == "all"
52
+ Provides-Extra: test
53
+ Requires-Dist: pytest>=8; extra == "test"
54
+ Dynamic: license-file
55
+
56
+ # Agent Harness Bridge
57
+
58
+ `agent-harness-bridge` gives applications one small, submit-tool-oriented API
59
+ for three different agent runtimes:
60
+
61
+ - OpenAI Agents SDK, including OpenAI-compatible endpoints such as Volcengine Ark
62
+ - Claude Agent SDK
63
+ - DeepSeek Harness (`dsh`)
64
+
65
+ It deliberately does not hide backend lifecycle differences. Each adapter owns
66
+ its native session continuation, MCP transport, timeout, cleanup and recovery
67
+ logic, while applications keep their prompts, domain tools and submit
68
+ validation.
69
+
70
+ ## Install
71
+
72
+ Install only the runtime you need, or all validated adapters:
73
+
74
+ ```bash
75
+ pip install 'agent-harness-bridge[openai]==0.1.0'
76
+ pip install 'agent-harness-bridge[claude]==0.1.0'
77
+ pip install 'agent-harness-bridge[deepseek]==0.1.0'
78
+ pip install 'agent-harness-bridge[all]==0.1.0'
79
+ ```
80
+
81
+ The dsh adapter also imports `deepseek_harness`. DeepSeek's current SDK
82
+ depends on a platform-specific runtime wheel, so the bridge does not force
83
+ that wheel onto every installation. Install the SDK using the method supported
84
+ by the target host. On older-glibc clusters, load `polyfill-glibc/0.1` before
85
+ using its runtime or point `DSH_BIN` at a validated source build.
86
+
87
+ ## Configuration
88
+
89
+ Harness and model selection are independent:
90
+
91
+ ```bash
92
+ HARNESS=openai MODEL=doubao-seed-2-1-turbo-260628 python your_workflow.py
93
+ HARNESS=openai MODEL=doubao-seed-2-1-pro-260628 python your_workflow.py
94
+ HARNESS=deepseek MODEL=doubao-seed-2-1-turbo-260628 python your_workflow.py
95
+ HARNESS=claude MODEL=claude-sonnet-5 python your_workflow.py
96
+ ```
97
+
98
+ The default remains OpenAI Agents SDK with
99
+ `doubao-seed-2-1-turbo-260628`. Model identifiers are intentionally open
100
+ strings rather than a hard-coded catalog.
101
+
102
+ ## Contract
103
+
104
+ Applications provide `ToolSpec` objects and designate one successful submit
105
+ tool as the completion condition:
106
+
107
+ ```python
108
+ from harness_bridge import ToolSpec, run_agent
109
+
110
+ async def submit(args):
111
+ return {
112
+ "content": [{"type": "text", "text": "accepted"}],
113
+ "_submitted": args,
114
+ }
115
+
116
+ result = await run_agent(
117
+ tools=[ToolSpec("submit_answer", "Submit the checked answer", {"answer": str}, submit)],
118
+ submit_tool="submit_answer",
119
+ prompt="Check the evidence and submit the answer.",
120
+ cwd="/absolute/read-only/workdir",
121
+ )
122
+ ```
123
+
124
+ Tool handlers return an MCP-shaped result containing text or image content,
125
+ an optional `is_error`, and an optional private `_submitted` value captured by
126
+ the host after successful validation. A handler that raises is reported to
127
+ the model as an error result under every backend; it never aborts the run.
128
+
129
+ `run_agent()` validates the tool table before importing any SDK: the submit
130
+ tool must be present, tool names must be unique, `allowed_builtin` must be a
131
+ subset of `read`, `glob`, `grep`, `tasks`, and application tools may not
132
+ reuse the name of a requested builtin.
133
+
134
+ `allowed_builtin` selects Claude Code's own Read/Glob/Grep/Task tools under
135
+ `HARNESS=claude`. The OpenAI and dsh adapters serve same-named, cwd-confined
136
+ host tools implemented in pure Python (Grep needs no `rg` on the host), so
137
+ prompts stay portable across backends.
138
+
139
+ `backend_capabilities()` exposes runtime facts that callers can check before a
140
+ run. Unsupported built-in capabilities fail closed.
141
+
142
+ ## Design boundary
143
+
144
+ The bridge owns only runtime concerns. Domain workflows should continue to own:
145
+
146
+ - prompts and scientific or business policy
147
+ - tool handler implementations
148
+ - submit validation
149
+ - output files and resume manifests
150
+
151
+ Backend-specific defenses remain adapter-local. In particular, OpenAI
152
+ Responses continuation and context reset, Claude SDK teardown and permissions,
153
+ and dsh MCP startup/watchdog/SSE recovery are not reduced to a lowest-common-
154
+ denominator loop.
@@ -0,0 +1,99 @@
1
+ # Agent Harness Bridge
2
+
3
+ `agent-harness-bridge` gives applications one small, submit-tool-oriented API
4
+ for three different agent runtimes:
5
+
6
+ - OpenAI Agents SDK, including OpenAI-compatible endpoints such as Volcengine Ark
7
+ - Claude Agent SDK
8
+ - DeepSeek Harness (`dsh`)
9
+
10
+ It deliberately does not hide backend lifecycle differences. Each adapter owns
11
+ its native session continuation, MCP transport, timeout, cleanup and recovery
12
+ logic, while applications keep their prompts, domain tools and submit
13
+ validation.
14
+
15
+ ## Install
16
+
17
+ Install only the runtime you need, or all validated adapters:
18
+
19
+ ```bash
20
+ pip install 'agent-harness-bridge[openai]==0.1.0'
21
+ pip install 'agent-harness-bridge[claude]==0.1.0'
22
+ pip install 'agent-harness-bridge[deepseek]==0.1.0'
23
+ pip install 'agent-harness-bridge[all]==0.1.0'
24
+ ```
25
+
26
+ The dsh adapter also imports `deepseek_harness`. DeepSeek's current SDK
27
+ depends on a platform-specific runtime wheel, so the bridge does not force
28
+ that wheel onto every installation. Install the SDK using the method supported
29
+ by the target host. On older-glibc clusters, load `polyfill-glibc/0.1` before
30
+ using its runtime or point `DSH_BIN` at a validated source build.
31
+
32
+ ## Configuration
33
+
34
+ Harness and model selection are independent:
35
+
36
+ ```bash
37
+ HARNESS=openai MODEL=doubao-seed-2-1-turbo-260628 python your_workflow.py
38
+ HARNESS=openai MODEL=doubao-seed-2-1-pro-260628 python your_workflow.py
39
+ HARNESS=deepseek MODEL=doubao-seed-2-1-turbo-260628 python your_workflow.py
40
+ HARNESS=claude MODEL=claude-sonnet-5 python your_workflow.py
41
+ ```
42
+
43
+ The default remains OpenAI Agents SDK with
44
+ `doubao-seed-2-1-turbo-260628`. Model identifiers are intentionally open
45
+ strings rather than a hard-coded catalog.
46
+
47
+ ## Contract
48
+
49
+ Applications provide `ToolSpec` objects and designate one successful submit
50
+ tool as the completion condition:
51
+
52
+ ```python
53
+ from harness_bridge import ToolSpec, run_agent
54
+
55
+ async def submit(args):
56
+ return {
57
+ "content": [{"type": "text", "text": "accepted"}],
58
+ "_submitted": args,
59
+ }
60
+
61
+ result = await run_agent(
62
+ tools=[ToolSpec("submit_answer", "Submit the checked answer", {"answer": str}, submit)],
63
+ submit_tool="submit_answer",
64
+ prompt="Check the evidence and submit the answer.",
65
+ cwd="/absolute/read-only/workdir",
66
+ )
67
+ ```
68
+
69
+ Tool handlers return an MCP-shaped result containing text or image content,
70
+ an optional `is_error`, and an optional private `_submitted` value captured by
71
+ the host after successful validation. A handler that raises is reported to
72
+ the model as an error result under every backend; it never aborts the run.
73
+
74
+ `run_agent()` validates the tool table before importing any SDK: the submit
75
+ tool must be present, tool names must be unique, `allowed_builtin` must be a
76
+ subset of `read`, `glob`, `grep`, `tasks`, and application tools may not
77
+ reuse the name of a requested builtin.
78
+
79
+ `allowed_builtin` selects Claude Code's own Read/Glob/Grep/Task tools under
80
+ `HARNESS=claude`. The OpenAI and dsh adapters serve same-named, cwd-confined
81
+ host tools implemented in pure Python (Grep needs no `rg` on the host), so
82
+ prompts stay portable across backends.
83
+
84
+ `backend_capabilities()` exposes runtime facts that callers can check before a
85
+ run. Unsupported built-in capabilities fail closed.
86
+
87
+ ## Design boundary
88
+
89
+ The bridge owns only runtime concerns. Domain workflows should continue to own:
90
+
91
+ - prompts and scientific or business policy
92
+ - tool handler implementations
93
+ - submit validation
94
+ - output files and resume manifests
95
+
96
+ Backend-specific defenses remain adapter-local. In particular, OpenAI
97
+ Responses continuation and context reset, Claude SDK teardown and permissions,
98
+ and dsh MCP startup/watchdog/SSE recovery are not reduced to a lowest-common-
99
+ denominator loop.
@@ -0,0 +1,154 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-harness-bridge
3
+ Version: 0.1.0
4
+ Summary: A small compatibility layer for OpenAI Agents SDK, Claude Agent SDK, and DeepSeek Harness
5
+ Author-email: chansigit <chansigit@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 chansigit
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/chansigit/agent-harness-bridge
29
+ Project-URL: Repository, https://github.com/chansigit/agent-harness-bridge
30
+ Project-URL: Issues, https://github.com/chansigit/agent-harness-bridge/issues
31
+ Classifier: Programming Language :: Python :: 3
32
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
33
+ Requires-Python: >=3.10
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Provides-Extra: openai
37
+ Requires-Dist: openai-agents==0.22.0; extra == "openai"
38
+ Provides-Extra: claude
39
+ Requires-Dist: claude-agent-sdk>=0.2.152; extra == "claude"
40
+ Provides-Extra: deepseek
41
+ Requires-Dist: mcp<2,>=1.19; extra == "deepseek"
42
+ Requires-Dist: PyYAML>=6; extra == "deepseek"
43
+ Requires-Dist: uvicorn>=0.30; extra == "deepseek"
44
+ Requires-Dist: sse-starlette<4,>=3; extra == "deepseek"
45
+ Provides-Extra: all
46
+ Requires-Dist: openai-agents==0.22.0; extra == "all"
47
+ Requires-Dist: claude-agent-sdk>=0.2.152; extra == "all"
48
+ Requires-Dist: mcp<2,>=1.19; extra == "all"
49
+ Requires-Dist: PyYAML>=6; extra == "all"
50
+ Requires-Dist: uvicorn>=0.30; extra == "all"
51
+ Requires-Dist: sse-starlette<4,>=3; extra == "all"
52
+ Provides-Extra: test
53
+ Requires-Dist: pytest>=8; extra == "test"
54
+ Dynamic: license-file
55
+
56
+ # Agent Harness Bridge
57
+
58
+ `agent-harness-bridge` gives applications one small, submit-tool-oriented API
59
+ for three different agent runtimes:
60
+
61
+ - OpenAI Agents SDK, including OpenAI-compatible endpoints such as Volcengine Ark
62
+ - Claude Agent SDK
63
+ - DeepSeek Harness (`dsh`)
64
+
65
+ It deliberately does not hide backend lifecycle differences. Each adapter owns
66
+ its native session continuation, MCP transport, timeout, cleanup and recovery
67
+ logic, while applications keep their prompts, domain tools and submit
68
+ validation.
69
+
70
+ ## Install
71
+
72
+ Install only the runtime you need, or all validated adapters:
73
+
74
+ ```bash
75
+ pip install 'agent-harness-bridge[openai]==0.1.0'
76
+ pip install 'agent-harness-bridge[claude]==0.1.0'
77
+ pip install 'agent-harness-bridge[deepseek]==0.1.0'
78
+ pip install 'agent-harness-bridge[all]==0.1.0'
79
+ ```
80
+
81
+ The dsh adapter also imports `deepseek_harness`. DeepSeek's current SDK
82
+ depends on a platform-specific runtime wheel, so the bridge does not force
83
+ that wheel onto every installation. Install the SDK using the method supported
84
+ by the target host. On older-glibc clusters, load `polyfill-glibc/0.1` before
85
+ using its runtime or point `DSH_BIN` at a validated source build.
86
+
87
+ ## Configuration
88
+
89
+ Harness and model selection are independent:
90
+
91
+ ```bash
92
+ HARNESS=openai MODEL=doubao-seed-2-1-turbo-260628 python your_workflow.py
93
+ HARNESS=openai MODEL=doubao-seed-2-1-pro-260628 python your_workflow.py
94
+ HARNESS=deepseek MODEL=doubao-seed-2-1-turbo-260628 python your_workflow.py
95
+ HARNESS=claude MODEL=claude-sonnet-5 python your_workflow.py
96
+ ```
97
+
98
+ The default remains OpenAI Agents SDK with
99
+ `doubao-seed-2-1-turbo-260628`. Model identifiers are intentionally open
100
+ strings rather than a hard-coded catalog.
101
+
102
+ ## Contract
103
+
104
+ Applications provide `ToolSpec` objects and designate one successful submit
105
+ tool as the completion condition:
106
+
107
+ ```python
108
+ from harness_bridge import ToolSpec, run_agent
109
+
110
+ async def submit(args):
111
+ return {
112
+ "content": [{"type": "text", "text": "accepted"}],
113
+ "_submitted": args,
114
+ }
115
+
116
+ result = await run_agent(
117
+ tools=[ToolSpec("submit_answer", "Submit the checked answer", {"answer": str}, submit)],
118
+ submit_tool="submit_answer",
119
+ prompt="Check the evidence and submit the answer.",
120
+ cwd="/absolute/read-only/workdir",
121
+ )
122
+ ```
123
+
124
+ Tool handlers return an MCP-shaped result containing text or image content,
125
+ an optional `is_error`, and an optional private `_submitted` value captured by
126
+ the host after successful validation. A handler that raises is reported to
127
+ the model as an error result under every backend; it never aborts the run.
128
+
129
+ `run_agent()` validates the tool table before importing any SDK: the submit
130
+ tool must be present, tool names must be unique, `allowed_builtin` must be a
131
+ subset of `read`, `glob`, `grep`, `tasks`, and application tools may not
132
+ reuse the name of a requested builtin.
133
+
134
+ `allowed_builtin` selects Claude Code's own Read/Glob/Grep/Task tools under
135
+ `HARNESS=claude`. The OpenAI and dsh adapters serve same-named, cwd-confined
136
+ host tools implemented in pure Python (Grep needs no `rg` on the host), so
137
+ prompts stay portable across backends.
138
+
139
+ `backend_capabilities()` exposes runtime facts that callers can check before a
140
+ run. Unsupported built-in capabilities fail closed.
141
+
142
+ ## Design boundary
143
+
144
+ The bridge owns only runtime concerns. Domain workflows should continue to own:
145
+
146
+ - prompts and scientific or business policy
147
+ - tool handler implementations
148
+ - submit validation
149
+ - output files and resume manifests
150
+
151
+ Backend-specific defenses remain adapter-local. In particular, OpenAI
152
+ Responses continuation and context reset, Claude SDK teardown and permissions,
153
+ and dsh MCP startup/watchdog/SSE recovery are not reduced to a lowest-common-
154
+ denominator loop.
@@ -0,0 +1,19 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ agent_harness_bridge.egg-info/PKG-INFO
5
+ agent_harness_bridge.egg-info/SOURCES.txt
6
+ agent_harness_bridge.egg-info/dependency_links.txt
7
+ agent_harness_bridge.egg-info/requires.txt
8
+ agent_harness_bridge.egg-info/top_level.txt
9
+ harness_bridge/__init__.py
10
+ harness_bridge/_harness_claude.py
11
+ harness_bridge/_harness_deepseek.py
12
+ harness_bridge/_harness_host_tools.py
13
+ harness_bridge/_harness_openai.py
14
+ harness_bridge/harness.py
15
+ tests/test_core.py
16
+ tests/test_deepseek_harness.py
17
+ tests/test_host_tools.py
18
+ tests/test_mcp_server_lifecycle.py
19
+ tests/test_openai_harness.py
@@ -0,0 +1,23 @@
1
+
2
+ [all]
3
+ openai-agents==0.22.0
4
+ claude-agent-sdk>=0.2.152
5
+ mcp<2,>=1.19
6
+ PyYAML>=6
7
+ uvicorn>=0.30
8
+ sse-starlette<4,>=3
9
+
10
+ [claude]
11
+ claude-agent-sdk>=0.2.152
12
+
13
+ [deepseek]
14
+ mcp<2,>=1.19
15
+ PyYAML>=6
16
+ uvicorn>=0.30
17
+ sse-starlette<4,>=3
18
+
19
+ [openai]
20
+ openai-agents==0.22.0
21
+
22
+ [test]
23
+ pytest>=8
@@ -0,0 +1,37 @@
1
+ """Stable public API for the agent harness bridge."""
2
+
3
+ from .harness import (
4
+ AgentConfig,
5
+ AgentIncompleteError,
6
+ AgentLimitExhausted,
7
+ AgentRunResult,
8
+ AgentTimeout,
9
+ HarnessCapabilities,
10
+ ToolSpec,
11
+ backend_capabilities,
12
+ backend_name,
13
+ default_model,
14
+ resolve_agent_config,
15
+ retry_transient,
16
+ run_agent,
17
+ wall_seconds,
18
+ )
19
+
20
+ __all__ = [
21
+ "AgentConfig",
22
+ "AgentIncompleteError",
23
+ "AgentLimitExhausted",
24
+ "AgentRunResult",
25
+ "AgentTimeout",
26
+ "HarnessCapabilities",
27
+ "ToolSpec",
28
+ "backend_capabilities",
29
+ "backend_name",
30
+ "default_model",
31
+ "resolve_agent_config",
32
+ "retry_transient",
33
+ "run_agent",
34
+ "wall_seconds",
35
+ ]
36
+
37
+ __version__ = "0.1.0"