openrath 1.0.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.
Files changed (220) hide show
  1. openrath-1.0.0/.flake8 +9 -0
  2. openrath-1.0.0/.gitignore +21 -0
  3. openrath-1.0.0/.python-version +1 -0
  4. openrath-1.0.0/CONTRIBUTING.md +98 -0
  5. openrath-1.0.0/LICENSE +29 -0
  6. openrath-1.0.0/PKG-INFO +400 -0
  7. openrath-1.0.0/README.md +348 -0
  8. openrath-1.0.0/docs/Makefile +16 -0
  9. openrath-1.0.0/docs/make.bat +19 -0
  10. openrath-1.0.0/docs/source/_static/backend.png +0 -0
  11. openrath-1.0.0/docs/source/_static/logo.png +0 -0
  12. openrath-1.0.0/docs/source/_static/openrath.css +118 -0
  13. openrath-1.0.0/docs/source/_static/research_transformer.png +0 -0
  14. openrath-1.0.0/docs/source/_static/session.png +0 -0
  15. openrath-1.0.0/docs/source/_static/workflow.png +0 -0
  16. openrath-1.0.0/docs/source/_templates/.gitkeep +0 -0
  17. openrath-1.0.0/docs/source/conf.py +219 -0
  18. openrath-1.0.0/docs/source/developer_notes/agent_param.md +107 -0
  19. openrath-1.0.0/docs/source/developer_notes/index.md +53 -0
  20. openrath-1.0.0/docs/source/developer_notes/llm.md +125 -0
  21. openrath-1.0.0/docs/source/developer_notes/sandbox.md +125 -0
  22. openrath-1.0.0/docs/source/developer_notes/session.md +126 -0
  23. openrath-1.0.0/docs/source/developer_notes/tool.md +139 -0
  24. openrath-1.0.0/docs/source/developer_notes/workflow.md +132 -0
  25. openrath-1.0.0/docs/source/index.md +78 -0
  26. openrath-1.0.0/docs/source/install.md +237 -0
  27. openrath-1.0.0/docs/source/reference/backend.md +142 -0
  28. openrath-1.0.0/docs/source/reference/flow.md +68 -0
  29. openrath-1.0.0/docs/source/reference/flow_tool.md +88 -0
  30. openrath-1.0.0/docs/source/reference/index.md +36 -0
  31. openrath-1.0.0/docs/source/reference/llm.md +109 -0
  32. openrath-1.0.0/docs/source/reference/rath.md +28 -0
  33. openrath-1.0.0/docs/source/reference/session.md +130 -0
  34. openrath-1.0.0/docs/source/reference/utils.md +28 -0
  35. openrath-1.0.0/docs/source/showcase/architecture_story.md +53 -0
  36. openrath-1.0.0/docs/source/showcase/developer_quickstart.md +81 -0
  37. openrath-1.0.0/docs/source/showcase/docs_strategy.md +58 -0
  38. openrath-1.0.0/docs/source/showcase/index.md +32 -0
  39. openrath-1.0.0/docs/source/showcase/one_page_pitch.md +54 -0
  40. openrath-1.0.0/docs/source/showcase/pytorch_analogy.md +54 -0
  41. openrath-1.0.0/docs/source/showcase/session_lifecycle.md +57 -0
  42. openrath-1.0.0/docs/source/showcase/tools_sandbox_story.md +51 -0
  43. openrath-1.0.0/docs/source/showcase/website_homepage_draft.md +43 -0
  44. openrath-1.0.0/docs/source/tutorial/assets/custom-flow-tool/html/custom-flow-tool-01-define-custom-tool.html +85 -0
  45. openrath-1.0.0/docs/source/tutorial/assets/custom-flow-tool/html/custom-flow-tool-02-run-custom-tool-loop.html +98 -0
  46. openrath-1.0.0/docs/source/tutorial/assets/custom-flow-tool/logs/custom-flow-tool-01-define-custom-tool.txt +18 -0
  47. openrath-1.0.0/docs/source/tutorial/assets/custom-flow-tool/logs/custom-flow-tool-02-run-custom-tool-loop.txt +31 -0
  48. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-01-open-local-backend.html +82 -0
  49. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-02-write-workspace-file.html +72 -0
  50. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-03-run-shell-command.html +75 -0
  51. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-04-read-file-and-run-code.html +83 -0
  52. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-05-close-local-sandbox.html +73 -0
  53. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-01-open-local-backend.txt +15 -0
  54. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-02-write-workspace-file.txt +5 -0
  55. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-03-run-shell-command.txt +8 -0
  56. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-04-read-file-and-run-code.txt +16 -0
  57. openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-05-close-local-sandbox.txt +6 -0
  58. openrath-1.0.0/docs/source/tutorial/assets/manifest.json +106 -0
  59. openrath-1.0.0/docs/source/tutorial/assets/session-basics/html/session-basics-01-create-sessions.html +90 -0
  60. openrath-1.0.0/docs/source/tutorial/assets/session-basics/html/session-basics-02-fork-and-detach.html +76 -0
  61. openrath-1.0.0/docs/source/tutorial/assets/session-basics/html/session-basics-03-lazy-local-sandbox.html +74 -0
  62. openrath-1.0.0/docs/source/tutorial/assets/session-basics/logs/session-basics-01-create-sessions.txt +23 -0
  63. openrath-1.0.0/docs/source/tutorial/assets/session-basics/logs/session-basics-02-fork-and-detach.txt +9 -0
  64. openrath-1.0.0/docs/source/tutorial/assets/session-basics/logs/session-basics-03-lazy-local-sandbox.txt +7 -0
  65. openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/html/session-loop-tools-01-prepare-scripted-llm.html +73 -0
  66. openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/html/session-loop-tools-02-run-session-loop.html +118 -0
  67. openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/html/session-loop-tools-03-verify-loop-side-effect.html +75 -0
  68. openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/logs/session-loop-tools-01-prepare-scripted-llm.txt +6 -0
  69. openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/logs/session-loop-tools-02-run-session-loop.txt +51 -0
  70. openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/logs/session-loop-tools-03-verify-loop-side-effect.txt +8 -0
  71. openrath-1.0.0/docs/source/tutorial/custom_flow_tool.md +89 -0
  72. openrath-1.0.0/docs/source/tutorial/examples/custom_tool_usage.md +41 -0
  73. openrath-1.0.0/docs/source/tutorial/examples/engineering_agents.md +100 -0
  74. openrath-1.0.0/docs/source/tutorial/examples/index.md +28 -0
  75. openrath-1.0.0/docs/source/tutorial/examples/sandbox_backend_local.md +41 -0
  76. openrath-1.0.0/docs/source/tutorial/examples/sandbox_backend_opensandbox.md +43 -0
  77. openrath-1.0.0/docs/source/tutorial/examples/session_usage.md +51 -0
  78. openrath-1.0.0/docs/source/tutorial/examples/trading_agents.md +111 -0
  79. openrath-1.0.0/docs/source/tutorial/figures.md +42 -0
  80. openrath-1.0.0/docs/source/tutorial/index.md +41 -0
  81. openrath-1.0.0/docs/source/tutorial/local_sandbox_tools.md +80 -0
  82. openrath-1.0.0/docs/source/tutorial/scripts/run_tutorial_steps.py +635 -0
  83. openrath-1.0.0/docs/source/tutorial/session_basics.md +56 -0
  84. openrath-1.0.0/docs/source/tutorial/session_loop_tools.md +75 -0
  85. openrath-1.0.0/docs/source/user_guide/backends.md +112 -0
  86. openrath-1.0.0/docs/source/user_guide/concepts.md +30 -0
  87. openrath-1.0.0/docs/source/user_guide/index.md +28 -0
  88. openrath-1.0.0/docs/source/user_guide/llm.md +93 -0
  89. openrath-1.0.0/docs/source/user_guide/main_components.md +43 -0
  90. openrath-1.0.0/docs/source/user_guide/session.md +120 -0
  91. openrath-1.0.0/docs/source/user_guide/tools.md +114 -0
  92. openrath-1.0.0/docs/source/user_guide/workflow_agent.md +124 -0
  93. openrath-1.0.0/example/_chunk_print.py +17 -0
  94. openrath-1.0.0/example/_openai_provider.py +17 -0
  95. openrath-1.0.0/example/custom_tool_usage.py +91 -0
  96. openrath-1.0.0/example/engineering_agents/README.md +84 -0
  97. openrath-1.0.0/example/engineering_agents/agents.py +36 -0
  98. openrath-1.0.0/example/engineering_agents/main.py +68 -0
  99. openrath-1.0.0/example/engineering_agents/workflows.py +128 -0
  100. openrath-1.0.0/example/research_transformer/.gitignore +2 -0
  101. openrath-1.0.0/example/research_transformer/README.md +84 -0
  102. openrath-1.0.0/example/research_transformer/__init__.py +5 -0
  103. openrath-1.0.0/example/research_transformer/main.py +126 -0
  104. openrath-1.0.0/example/research_transformer/prompts.py +57 -0
  105. openrath-1.0.0/example/research_transformer/providers.py +75 -0
  106. openrath-1.0.0/example/research_transformer/tools.py +87 -0
  107. openrath-1.0.0/example/research_transformer/workflow.py +200 -0
  108. openrath-1.0.0/example/sandbox_backend_local.py +43 -0
  109. openrath-1.0.0/example/sandbox_backend_opensandbox.py +43 -0
  110. openrath-1.0.0/example/session_usage.py +36 -0
  111. openrath-1.0.0/example/trading_agents/README.md +67 -0
  112. openrath-1.0.0/example/trading_agents/_env.py +36 -0
  113. openrath-1.0.0/example/trading_agents/agents.py +44 -0
  114. openrath-1.0.0/example/trading_agents/main.py +69 -0
  115. openrath-1.0.0/example/trading_agents/tools.py +118 -0
  116. openrath-1.0.0/example/trading_agents/workflow.py +77 -0
  117. openrath-1.0.0/mypy.ini +12 -0
  118. openrath-1.0.0/pyproject.toml +50 -0
  119. openrath-1.0.0/pytest.ini +9 -0
  120. openrath-1.0.0/scripts/build_docs.bat +27 -0
  121. openrath-1.0.0/scripts/build_docs.sh +18 -0
  122. openrath-1.0.0/scripts/build_python_package.bat +20 -0
  123. openrath-1.0.0/scripts/build_python_package.sh +18 -0
  124. openrath-1.0.0/scripts/check_opensandbox.bat +63 -0
  125. openrath-1.0.0/scripts/check_opensandbox.sh +69 -0
  126. openrath-1.0.0/scripts/launch_opensandbox.bat +64 -0
  127. openrath-1.0.0/scripts/launch_opensandbox.sh +48 -0
  128. openrath-1.0.0/scripts/run_openrath_test.bat +43 -0
  129. openrath-1.0.0/scripts/run_openrath_test.sh +24 -0
  130. openrath-1.0.0/src/rath/__init__.py +26 -0
  131. openrath-1.0.0/src/rath/backend/__init__.py +87 -0
  132. openrath-1.0.0/src/rath/backend/abc.py +135 -0
  133. openrath-1.0.0/src/rath/backend/capabilities.py +31 -0
  134. openrath-1.0.0/src/rath/backend/dedicated_loop.py +61 -0
  135. openrath-1.0.0/src/rath/backend/errors.py +47 -0
  136. openrath-1.0.0/src/rath/backend/local.py +316 -0
  137. openrath-1.0.0/src/rath/backend/opensandbox.py +521 -0
  138. openrath-1.0.0/src/rath/backend/registry.py +95 -0
  139. openrath-1.0.0/src/rath/backend/results.py +100 -0
  140. openrath-1.0.0/src/rath/backend/stream.py +186 -0
  141. openrath-1.0.0/src/rath/backend/tool_types.py +73 -0
  142. openrath-1.0.0/src/rath/flow/__init__.py +16 -0
  143. openrath-1.0.0/src/rath/flow/agent.py +42 -0
  144. openrath-1.0.0/src/rath/flow/agent_param.py +56 -0
  145. openrath-1.0.0/src/rath/flow/compressor.py +35 -0
  146. openrath-1.0.0/src/rath/flow/tool/__init__.py +56 -0
  147. openrath-1.0.0/src/rath/flow/tool/base.py +33 -0
  148. openrath-1.0.0/src/rath/flow/tool/system_tool.py +173 -0
  149. openrath-1.0.0/src/rath/flow/tool/tool_table.py +43 -0
  150. openrath-1.0.0/src/rath/flow/workflow.py +73 -0
  151. openrath-1.0.0/src/rath/llm/__init__.py +39 -0
  152. openrath-1.0.0/src/rath/llm/chat_request.py +77 -0
  153. openrath-1.0.0/src/rath/llm/chat_response.py +95 -0
  154. openrath-1.0.0/src/rath/llm/client.py +42 -0
  155. openrath-1.0.0/src/rath/llm/openai_create_kwargs.py +130 -0
  156. openrath-1.0.0/src/rath/llm/openai_normalize.py +177 -0
  157. openrath-1.0.0/src/rath/llm/provider.py +58 -0
  158. openrath-1.0.0/src/rath/py.typed +0 -0
  159. openrath-1.0.0/src/rath/session/__init__.py +89 -0
  160. openrath-1.0.0/src/rath/session/chat_request_build.py +55 -0
  161. openrath-1.0.0/src/rath/session/chunk.py +178 -0
  162. openrath-1.0.0/src/rath/session/compress.py +139 -0
  163. openrath-1.0.0/src/rath/session/graph/__init__.py +44 -0
  164. openrath-1.0.0/src/rath/session/graph/kind.py +25 -0
  165. openrath-1.0.0/src/rath/session/graph/legacy.py +23 -0
  166. openrath-1.0.0/src/rath/session/graph/recording.py +115 -0
  167. openrath-1.0.0/src/rath/session/graph/traverse.py +136 -0
  168. openrath-1.0.0/src/rath/session/loop.py +382 -0
  169. openrath-1.0.0/src/rath/session/manager.py +44 -0
  170. openrath-1.0.0/src/rath/session/primitives.py +64 -0
  171. openrath-1.0.0/src/rath/session/provider_builtin.py +47 -0
  172. openrath-1.0.0/src/rath/session/session.py +295 -0
  173. openrath-1.0.0/src/rath/utils/__init__.py +28 -0
  174. openrath-1.0.0/src/rath/utils/decoding.py +38 -0
  175. openrath-1.0.0/src/rath/utils/env.py +52 -0
  176. openrath-1.0.0/tests/__init__.py +0 -0
  177. openrath-1.0.0/tests/backends/__init__.py +0 -0
  178. openrath-1.0.0/tests/backends/test_local.py +85 -0
  179. openrath-1.0.0/tests/backends/test_opensandbox.py +145 -0
  180. openrath-1.0.0/tests/conformance/__init__.py +0 -0
  181. openrath-1.0.0/tests/conformance/conftest.py +36 -0
  182. openrath-1.0.0/tests/conformance/test_cancellation.py +27 -0
  183. openrath-1.0.0/tests/conformance/test_code_run.py +30 -0
  184. openrath-1.0.0/tests/conformance/test_command_run.py +115 -0
  185. openrath-1.0.0/tests/conformance/test_concurrency.py +56 -0
  186. openrath-1.0.0/tests/conformance/test_files.py +69 -0
  187. openrath-1.0.0/tests/conformance/test_lifecycle.py +53 -0
  188. openrath-1.0.0/tests/conformance/test_stream_event.py +95 -0
  189. openrath-1.0.0/tests/conftest.py +34 -0
  190. openrath-1.0.0/tests/example/test_research_transformer_cli.py +182 -0
  191. openrath-1.0.0/tests/flow/test_flow_tool_user_subclass.py +104 -0
  192. openrath-1.0.0/tests/flow/test_workflow_agent.py +72 -0
  193. openrath-1.0.0/tests/integration/test_session_compress_real.py +180 -0
  194. openrath-1.0.0/tests/integration/test_session_loop_real.py +143 -0
  195. openrath-1.0.0/tests/llm/test_openai_chat_real.py +118 -0
  196. openrath-1.0.0/tests/openai_env_provider.py +17 -0
  197. openrath-1.0.0/tests/session/scripted_loop_executor.py +35 -0
  198. openrath-1.0.0/tests/session/test_chunk_messages.py +86 -0
  199. openrath-1.0.0/tests/session/test_lineage_graph_unit.py +105 -0
  200. openrath-1.0.0/tests/session/test_llm_message_wire.py +57 -0
  201. openrath-1.0.0/tests/session/test_run_session_loop_edges.py +354 -0
  202. openrath-1.0.0/tests/session/test_run_session_loop_local.py +222 -0
  203. openrath-1.0.0/tests/session/test_session_fork_detach_merge.py +43 -0
  204. openrath-1.0.0/tests/session/test_session_primitives.py +41 -0
  205. openrath-1.0.0/tests/session/test_session_registry.py +28 -0
  206. openrath-1.0.0/tests/session/test_session_sandbox_behavior.py +103 -0
  207. openrath-1.0.0/tests/session/test_tool_registry.py +99 -0
  208. openrath-1.0.0/tests/test_import.py +89 -0
  209. openrath-1.0.0/tests/unit/__init__.py +0 -0
  210. openrath-1.0.0/tests/unit/test_calls.py +106 -0
  211. openrath-1.0.0/tests/unit/test_capabilities.py +60 -0
  212. openrath-1.0.0/tests/unit/test_decoding.py +30 -0
  213. openrath-1.0.0/tests/unit/test_errors.py +58 -0
  214. openrath-1.0.0/tests/unit/test_flow_tool.py +67 -0
  215. openrath-1.0.0/tests/unit/test_opensandbox_bind_fallback.py +37 -0
  216. openrath-1.0.0/tests/unit/test_opensandbox_workspace_volume.py +47 -0
  217. openrath-1.0.0/tests/unit/test_registry.py +157 -0
  218. openrath-1.0.0/tests/unit/test_results.py +71 -0
  219. openrath-1.0.0/tests/unit/test_stream.py +199 -0
  220. openrath-1.0.0/uv.lock +1589 -0
openrath-1.0.0/.flake8 ADDED
@@ -0,0 +1,9 @@
1
+ [flake8]
2
+ max-line-length = 88
3
+ # Match common Black/Ruff stacks; line length is not enforced strictly here.
4
+ extend-ignore = E203, E501
5
+ exclude =
6
+ .git,
7
+ .venv,
8
+ build,
9
+ dist
@@ -0,0 +1,21 @@
1
+ .venv/
2
+ .mypy_cache/
3
+ .pytest_cache/
4
+ __pycache__/
5
+ *.py[cod]
6
+ *.egg-info/
7
+ dist/
8
+ build/
9
+ htmlcov/
10
+ .coverage
11
+ .coverage.*
12
+
13
+ # Local env file (optional); not read by OpenRath — export vars in your shell instead.
14
+ .env
15
+ .workspace/
16
+
17
+ # OpenSandbox
18
+ .sandbox.toml
19
+
20
+ # Sphinx
21
+ docs/_build/
@@ -0,0 +1 @@
1
+ 3.10
@@ -0,0 +1,98 @@
1
+ # Contributing to OpenRath
2
+
3
+ Thank you for helping improve OpenRath. This document matches the current repo layout and tool chain. For day-to-day work, treat contributions as **small, verifiable steps**: clarify scope, implement, then run the checks below before opening a pull request.
4
+
5
+ ## Project goals (keep the core small)
6
+
7
+ - **Session-first**: chunk tables, loops, and sandbox backends should stay easy to reason about.
8
+ - **Composable APIs**: workflows and agent parameters should feel natural to combine (PyTorch-like ergonomics without copying PyTorch).
9
+ - **Focused changes**: avoid drive-by refactors and unrelated formatting in the same PR as a feature or fix.
10
+ - **Design before large moves**: session graph semantics, tool wiring, and major public surfaces deserve a short design note or issue thread before big diffs.
11
+
12
+ ## Development environment
13
+
14
+ Requirements: **Python 3.10–3.13** (see `requires-python` in `pyproject.toml`).
15
+
16
+ We use **[uv](https://github.com/astral-sh/uv)** for environments.
17
+
18
+ ```bash
19
+ # Runtime + dev tools (flake8, mypy, pytest)
20
+ uv sync --group dev
21
+ ```
22
+
23
+ Optional groups:
24
+
25
+ ```bash
26
+ # Editable install with OpenSandbox extras (for backend work)
27
+ uv sync --group dev --extra opensandbox
28
+
29
+ # Sphinx + extensions (for documentation edits)
30
+ uv sync --group dev --group docs
31
+ ```
32
+
33
+ Run Python tools through `uv run …` so they use the synced environment.
34
+
35
+ ## Verify before you push
36
+
37
+ These commands are what maintainers expect to pass on a typical PR (library code, tests, and **examples**):
38
+
39
+ ```bash
40
+ uv run flake8 src tests example
41
+ uv run mypy src
42
+ uv run pytest
43
+ ```
44
+
45
+ Notes:
46
+
47
+ - **`mypy`** is run on `src/` only (package API surface). If you change typing at boundaries, keep `src` clean.
48
+ - **`flake8`** includes **`example/`**: scripts under `example/` are part of the reviewed surface.
49
+ - **`pytest`** runs the full tree. Many tests run **offline**; some are **conditional** (see below).
50
+
51
+ ### Optional / live test tiers
52
+
53
+ | Kind | When they run | What you need |
54
+ |------|----------------|---------------|
55
+ | **Default unit & conformance** | Always (unless skipped internally) | Nothing special |
56
+ | **`live_llm` / `integration`** | Skip if `OPENAI_API_KEY` is unset or very short | Valid `OPENAI_API_KEY`; sometimes `OPENAI_DEFAULT_MODEL` / base URL per test docstrings |
57
+ | **`opensandbox`** | Skip if no server on `localhost:8080` (configurable via `OPENSANDBOX_TEST_HOST` / `PORT`) | Running OpenSandbox stack; see `tests/conftest.py` and repo scripts under `scripts/` |
58
+
59
+ Do not commit secrets. Use environment variables or local-only config.
60
+
61
+ ### Documentation build
62
+
63
+ If you change `docs/`, build HTML locally:
64
+
65
+ ```bash
66
+ uv sync --group dev --group docs
67
+ uv run sphinx-build -M html docs/source docs/_build
68
+ ```
69
+
70
+ Open `docs/_build/html/index.html` in a browser.
71
+
72
+ ## Repository layout
73
+
74
+ ```text
75
+ src/rath/ Installable package (wheel maps here via hatch)
76
+ tests/ pytest tree (unit, integration, conformance, examples checks)
77
+ example/ Runnable demos and CLI entry points (also flake8-clean)
78
+ docs/source/ Sphinx + MyST sources
79
+ pyproject.toml Metadata, dependencies, dependency groups
80
+ ```
81
+
82
+ ## Code and review checklist
83
+
84
+ 1. **Scope**: One PR should solve one problem (or one tightly related cluster).
85
+ 2. **Tests**: Add or update tests for behavior changes; keep fast tests deterministic without network when possible.
86
+ 3. **Public behavior**: Update `README.md`, user-facing docstrings, or `docs/` when CLI or semantics change.
87
+ 4. **Style**: Prefer clear names and short module docstrings over long inline chatter. Keep `pragma: no cover` lines purposeful and explained.
88
+ 5. **Examples**: If you touch `example/`, run entry points mentally (or briefly) and ensure new env vars are documented in the relevant `README.md` there.
89
+
90
+ ## Pull requests
91
+
92
+ - Describe **motivation**, **what changed**, and **how you verified** it (commands run).
93
+ - Link related issues when applicable.
94
+ - Call out **breaking changes**, **follow-ups**, or **known limitations** explicitly.
95
+
96
+ ## License
97
+
98
+ By contributing, you agree your contributions are licensed under the **BSD 3-Clause License** in this repository (`LICENSE`).
openrath-1.0.0/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Rath Team
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its contributors
17
+ may be used to endorse or promote products derived from this software
18
+ without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF
29
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,400 @@
1
+ Metadata-Version: 2.4
2
+ Name: openrath
3
+ Version: 1.0.0
4
+ Summary: An open-source, torch-like API framework for dynamic multi-agent workflow.
5
+ Project-URL: Homepage, https://github.com/Rath-Team/OpenRath
6
+ Project-URL: Repository, https://github.com/Rath-Team/OpenRath
7
+ Project-URL: Bug Tracker, https://github.com/Rath-Team/OpenRath/issues
8
+ License: BSD 3-Clause License
9
+
10
+ Copyright (c) 2026, Rath Team
11
+ All rights reserved.
12
+
13
+ Redistribution and use in source and binary forms, with or without
14
+ modification, are permitted provided that the following conditions are met:
15
+
16
+ 1. Redistributions of source code must retain the above copyright notice, this
17
+ list of conditions and the following disclaimer.
18
+
19
+ 2. Redistributions in binary form must reproduce the above copyright notice,
20
+ this list of conditions and the following disclaimer in the documentation
21
+ and/or other materials provided with the distribution.
22
+
23
+ 3. Neither the name of the copyright holder nor the names of its contributors
24
+ may be used to endorse or promote products derived from this software
25
+ without specific prior written permission.
26
+
27
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
28
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
31
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32
+ DAMAGES INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER
34
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35
+ OR TORT INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF
36
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
+ License-File: LICENSE
38
+ Classifier: License :: OSI Approved :: BSD License
39
+ Classifier: Programming Language :: Python :: 3
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Programming Language :: Python :: 3.13
44
+ Requires-Python: <3.14,>=3.10
45
+ Requires-Dist: openai>=1.0.0
46
+ Requires-Dist: pydantic<3,>=2.0.0
47
+ Provides-Extra: opensandbox
48
+ Requires-Dist: opensandbox-code-interpreter>=0.1.2; extra == 'opensandbox'
49
+ Requires-Dist: opensandbox-server>=0.1.12; extra == 'opensandbox'
50
+ Requires-Dist: opensandbox>=0.1.7; extra == 'opensandbox'
51
+ Description-Content-Type: text/markdown
52
+
53
+ # OpenRath
54
+
55
+ ![OpenRath logo](https://raw.githubusercontent.com/Rath-Team/OpenRath/main/docs/source/_static/logo.png)
56
+
57
+ **OpenRath** is an open-source multi-agent framework. You can compose APIs in a PyTorch-like style: session lifecycle, workflow orchestration, tool dispatch, and sandbox backends evolve together on a session graph woven from agents and sessions.
58
+
59
+ ## Recent updates
60
+
61
+ - 2026-05-12: Released `v1.0.0` and opened the codebase and docs to the community.
62
+
63
+ > For more info on OpenRath, head over to our docs [https://openrath.terox.cn/index.html](https://openrath.terox.cn/index.html).
64
+
65
+ ---
66
+
67
+ ## Core highlights
68
+
69
+ Many stacks keep conversation state, orchestration logic, and execution environments separate: each agent holds its own message list or inner while-loop, the outer layer uses graphs or hand-written steps, and sandboxes or shells are bolted on later. That works for demos, but whole histories get copied across agent boundaries, the execution environment drifts from the workspace the session points at, and at cluster scale it is hard to say which branch and context a round belongs to. OpenRath treats the session as the primary carrier through a run (analogous to a tensor advancing through computation, without replacing PyTorch itself). The split differs in five ways below.
70
+
71
+ ### Sandbox as the execution backend of a session
72
+
73
+ Separate ledgers for messages and where commands actually run stay in sync only by hand. After machine or directory changes, or tighter isolation, tool landing points and the workspace implied by the conversation often diverge, which hurts reproducibility and audit. Here backend choice chain-loads off the same object, much like putting data on a device. After a dialogue-and-tool round, ownership of the active sandbox is written back into the returned session so later dispatch still targets the same workflow outcome.
74
+
75
+ ![Sandbox as session backend](https://raw.githubusercontent.com/Rath-Team/OpenRath/main/docs/source/_static/backend.png)
76
+
77
+ ### Context through chunk tables for better reuse in multi-agent collaboration
78
+
79
+ Flat message lists encourage whole-history copies and repeated stitching of system prompts and tool results, so it is hard to grab semantic slices while context length and traffic grow. This project keeps an ordered chunk table for system, user, assistant, tool feedback, and related rows; agent-side instructions are prepended before user chunks in the loop for structured sharing and composition. Session fork and merge primitives are described in the Session chapter of the user guide.
80
+
81
+ ### Session-first loops instead of agent-first loops for a sparse agent cluster
82
+
83
+ A common pattern is a small inner loop per agent (read, model, tools) wrapped by outer orchestration, which yields nested loops and unnecessary completions at a fixed cadence when many roles exist. The default path is session-centric: completions and tool rounds interleave on one evolving session; agents attach to the workflow mainly as prompts and sampling configuration, not each with its own closed executor, which fits sparse clusters better when only part of the roles should activate.
84
+
85
+ ![Session-first loop](https://raw.githubusercontent.com/Rath-Team/OpenRath/main/docs/source/_static/session.png)
86
+
87
+ ### Dynamic multi-agent fleets: automatic session-graph tracking
88
+
89
+ When topology is wired by hand or an external DAG, lineage often depends on ad-hoc IDs and log excerpts. At scale it becomes hard to say which fork or merge produced a given output. With session-graph tracking enabled, new sessions carry lineage metadata and register centrally into a queryable session graph for dialogue and tool traces; this has nothing to do with autograd and only records execution and conversation.
90
+
91
+ ### Modular workflows: compose and orchestrate cleanly
92
+
93
+ If one agent type owns prompts, network I/O, tools, and the loop, inheritance and callbacks stack up and even changing a system prompt or sampling field pulls the whole class. Workflows expose a forward step that takes a session and returns an updated session; agent-side settings sit in parameter-like objects; networking and sandbox dispatch live with the loop executor so module boundaries stay clearer for nesting and reuse.
94
+
95
+ ![Workflow composition](https://raw.githubusercontent.com/Rath-Team/OpenRath/main/docs/source/_static/workflow.png)
96
+
97
+ ---
98
+
99
+ ## Quickstart
100
+
101
+ ### Install from PyPI
102
+
103
+ ```bash
104
+ pip install openrath
105
+ ```
106
+
107
+ Optional OpenSandbox dependencies:
108
+
109
+ ```bash
110
+ pip install "openrath[opensandbox]"
111
+ ```
112
+
113
+ ### Install from source
114
+
115
+ ```bash
116
+ git clone https://github.com/Rath-Team/OpenRath.git
117
+ cd OpenRath
118
+ pip install .
119
+ ```
120
+
121
+ ### Configure the OpenSandbox backend (optional)
122
+
123
+ ```bash
124
+ pip install "openrath[opensandbox]"
125
+ # or: pip install ".[opensandbox]"
126
+ ```
127
+
128
+ You need a running OpenSandbox server (typically Docker). At the repo root, use `scripts/launch_opensandbox.sh` or `launch_opensandbox.bat` to sync the optional dependency, generate `.sandbox.toml`, and start `opensandbox-server`; see the script comments for details.
129
+
130
+ Export `OPEN_SANDBOX_DOMAIN` (default if unset in check scripts: `127.0.0.1:8080`) and any API keys your deployment requires. Run `scripts/check_opensandbox.sh` or `check_opensandbox.bat` to verify imports and `GET /health`.
131
+
132
+ Set the backend to `opensandbox` in-session with a spec; see `example/sandbox_backend_opensandbox.py` and the user guide chapter on sandbox backends.
133
+
134
+ ---
135
+
136
+ ## Documentation
137
+
138
+ Build Sphinx locally:
139
+
140
+ ```bash
141
+ git clone https://github.com/Rath-Team/OpenRath.git
142
+ uv sync --group dev --group docs
143
+ uv run sphinx-build -M html docs/source docs/_build
144
+ ```
145
+
146
+ The HTML output is under `docs/_build/html/`.
147
+
148
+ ---
149
+
150
+ ## Examples
151
+
152
+ Sample OpenRath entry points:
153
+
154
+ 1. [`session_usage.py`](example/session_usage.py): fork and detach, session loop with a local workspace binding, plus session compression at the main entry.
155
+ 2. [`sandbox_backend_local.py`](example/sandbox_backend_local.py): session loop on the local subprocess sandbox; compares unbound workspace vs binding the repository root as the workspace.
156
+ 3. [`sandbox_backend_opensandbox.py`](example/sandbox_backend_opensandbox.py): same shape on the OpenSandbox backend; requires an OpenSandbox stack.
157
+ 4. [`custom_tool_usage.py`](example/custom_tool_usage.py): FlowToolCall subclass and tool mode wiring on the model side.
158
+ 5. [`trading_agents/`](example/trading_agents/): an OpenRath reimplementation of [TradingAgents](https://github.com/TauricResearch/TradingAgents) (Tauric Research, multi-agent LLM finance stack). Roles stay in a workflow; sessions and tools follow this framework; CLI entry is `main.py`.
159
+ 6. [`engineering_agents/`](example/engineering_agents/): an OpenRath reimplementation of one scenario from [ClawTeam](https://github.com/HKUDS/ClawTeam) (HKUDS, multi-agent software-engineering automation). Nested workflows (e.g. Lead, FeatureSquad, backend pairs, QA) live in the subfolder.
160
+ 7. [`research_transformer/`](example/research_transformer/): a **Transformer-metaphor** academic pipeline (literature vs reproduction branches over N layers, optional figure tool, final polish) demonstrating story-first composition on `Session`/`Workflow`; default sandbox root is `example/research_transformer/.workspace/`.
161
+
162
+ <div align="center">
163
+ <img src="https://raw.githubusercontent.com/Rath-Team/OpenRath/main/docs/source/_static/research_transformer.png" alt="Research Transformer" style="width: 360px; height: auto;" />
164
+ </div>
165
+
166
+ The folders above that reimplement or storyboard upstream scenarios (`trading_agents`, `engineering_agents`, and similar) are for demonstrating complex orchestration only; they are not guarantees about upstream behavior. Using upstream names still means following those repositories’ licenses and terms.
167
+
168
+ ---
169
+
170
+ ## How OpenRath maps onto PyTorch
171
+
172
+ | Layer | PyTorch | OpenRath | Brief parallel |
173
+ | ----- | ------- | -------- | -------------- |
174
+ | Flowing carrier | Tensor | Session | Advances along compute or dialogue; state can be read again and appended. |
175
+ | Execution structure | Compute graph | Session Graph | Graphs encode dependencies; sessions carry multi-agent dialogue and tool traces. |
176
+ | Execution backend | GPU / CPU | Sandbox | Where compute lands maps to the isolation environment where commands and tools actually run. |
177
+ | Invoke surface | Kernel / op | Tool | Smallest callable surface the backend actually executes. |
178
+ | State / hyperparameters | `nn.Parameter` | `flow.AgentParam` | Agents are not classic executors; the object is closer to typed configuration or parameters. |
179
+ | Modularity | `nn.Module` | `flow.Workflow` | Recursive composition of child modules. |
180
+
181
+ 1. **Session / tensor**
182
+
183
+ In OpenRath a session carries ordered semantic chunks, not a numeric array. Like a tensor in PyTorch at the center of data flow and execution, fork and detach names follow PyTorch habits.
184
+
185
+ In OpenRath
186
+
187
+ ```python
188
+ from rath.session import Session
189
+
190
+ a = Session.from_user_message(
191
+ "Please impl a full-stack todo app with auth, DB, React frontend."
192
+ )
193
+ b = a.fork() # like clone()
194
+ c = a.detach()
195
+ ```
196
+
197
+ In PyTorch
198
+
199
+ ```python
200
+ import torch
201
+
202
+ a = torch.ones(3, requires_grad=True)
203
+ b = a.clone()
204
+ c = a.detach()
205
+ ```
206
+
207
+ 2. **Session graph / compute graph**
208
+
209
+ In PyTorch a multiply attaches the new tensor to the graph and `grad_fn` points at the backward node; after `detach` on a leaf, `grad_fn` is None. In OpenRath the session tracks identity and fork metadata: each session has a stable id, fork products record parent session ids, and detach products no longer declare a parent chain.
210
+
211
+ In OpenRath
212
+
213
+ ```python
214
+ from rath.session import Session
215
+
216
+ a = Session.from_user_message("Hello, how are you?")
217
+ b = a.fork()
218
+ c = a.detach()
219
+
220
+ print(a.id)
221
+ print(b.parent_session_ids)
222
+ print(c.parent_session_ids)
223
+ ```
224
+
225
+ In PyTorch
226
+
227
+ ```python
228
+ import torch
229
+
230
+ a = torch.tensor([1.0], requires_grad=True)
231
+ b = a * 2
232
+ c = a.detach()
233
+
234
+ print("a:", a)
235
+ print("b grad_fn:", b.grad_fn)
236
+ print("c.grad_fn:", c.grad_fn)
237
+ ```
238
+
239
+ 3. **Sandbox / device**
240
+
241
+ OpenRath models the sandbox backend in a device-like way: the session binds to an execution environment and working directory; chunk contents are not automatically rewritten when you rebind. The API mirrors PyTorch’s `to(device)` pattern: build the object, then declare where it runs.
242
+
243
+ In OpenRath
244
+
245
+ ```python
246
+ from rath.session import Session
247
+
248
+ a = Session.from_user_message(
249
+ "Please impl a full-stack todo app with auth, DB, React frontend."
250
+ )
251
+ a = a.to("local", spec="./") # spec: host workspace path
252
+ a = a.to("opensandbox", spec="./")
253
+ ```
254
+
255
+ In PyTorch
256
+
257
+ ```python
258
+ import torch
259
+
260
+ a = torch.ones(2, 3)
261
+ a = a.to("cuda:0")
262
+ ```
263
+
264
+ 4. **Kernel / tool**
265
+
266
+ In PyTorch, kernels or high-level ops take placed tensors, run numerically on that device, and return tensors. In OpenRath, the tool path takes structured payloads; the current sandbox interprets them inside an isolation boundary and returns command or file feedback into session chunks.
267
+
268
+ The call shapes line up: prepare inputs, invoke a thin API, and let the runtime do the heavy work.
269
+
270
+ In OpenRath
271
+
272
+ ```python
273
+ from rath.flow.tool import flow_tool_files_list
274
+ from rath.session import Session
275
+
276
+ a = Session.from_user_message(
277
+ "Please impl a full-stack todo app with auth, DB, React frontend."
278
+ )
279
+ a = a.to("local", spec="./")
280
+
281
+ tool_result = flow_tool_files_list(a, path="./")
282
+ ```
283
+
284
+ In PyTorch
285
+
286
+ ```python
287
+ import torch
288
+ import torch.nn.functional as F
289
+
290
+ logits = torch.tensor(
291
+ [
292
+ [2.0, 1.0, 0.1, -1.0, 0.3],
293
+ [0.2, 3.1, 0.5, 0.1, -0.4],
294
+ [1.2, 0.7, 2.5, 0.3, 0.1],
295
+ ]
296
+ )
297
+ target = torch.tensor([0, 1, 2])
298
+
299
+ loss = F.cross_entropy(logits, target)
300
+ ```
301
+
302
+ 5. **Agent state / parameters**
303
+
304
+ Module parameters in PyTorch register on the module dict and optimizers collect tensors by name. `AgentParam` in OpenRath binds two pieces into one: agent-side session chunks seeded from the agent prompt (a stable prefix before each completion) and a `Provider` with model name and sampling-style request fields.
305
+
306
+ In OpenRath
307
+
308
+ ```python
309
+ from rath import flow
310
+ from rath.session import Session
311
+
312
+ agent = flow.AgentParam(
313
+ agent_session=Session.from_agent_prompt("You are a helpful assistant."),
314
+ provider=flow.Provider(model="glm-5.1"),
315
+ )
316
+ ```
317
+
318
+ In PyTorch
319
+
320
+ ```python
321
+ import torch
322
+ from torch import nn
323
+
324
+ weight = nn.Parameter(torch.randn(1024, 4096))
325
+ ```
326
+
327
+ 6. **Workflow / module**
328
+
329
+ Workflow code stays modular and composable, much like PyTorch `Module`. With sessions and chunks maintained by the framework, implementers mainly structure workflow composition and business logic.
330
+
331
+ In OpenRath
332
+
333
+ ```python
334
+ from rath import flow
335
+ from rath.flow.tool import FlowToolCall
336
+ from rath.session import Session, run_session_loop
337
+
338
+
339
+ class Agent(flow.Workflow):
340
+ def __init__(
341
+ self,
342
+ system_prompt: str,
343
+ provider: flow.Provider,
344
+ tools: list[FlowToolCall] | None = None,
345
+ ) -> None:
346
+ super().__init__()
347
+ self.tools = list(tools or [])
348
+ self.agent = flow.AgentParam(
349
+ agent_session=Session.from_agent_prompt(system_prompt),
350
+ provider=provider,
351
+ )
352
+
353
+ def forward(self, session: Session) -> Session:
354
+ return run_session_loop(
355
+ user_session=session,
356
+ agent_session=self.agent.agent_session,
357
+ agent_provider=self.agent.provider,
358
+ tools=self.tools,
359
+ )
360
+
361
+
362
+ agent_model = Agent(
363
+ system_prompt="You are a helpful assistant.",
364
+ provider=flow.Provider(model="glm-5.1"),
365
+ )
366
+
367
+ user_session = Session.from_user_message(
368
+ "List all files in the current directory. Summarize what you found."
369
+ )
370
+ user_session = user_session.to("local", spec="./")
371
+ out_session = agent_model(user_session)
372
+ ```
373
+
374
+ In PyTorch
375
+
376
+ ```python
377
+ import torch
378
+ import torch.nn as nn
379
+
380
+
381
+ class Linear(nn.Module):
382
+ def __init__(self, in_features: int, out_features: int) -> None:
383
+ super().__init__()
384
+ self.weight = nn.Parameter(torch.randn(out_features, in_features))
385
+ self.bias = nn.Parameter(torch.zeros(out_features))
386
+
387
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
388
+ return x @ self.weight.T + self.bias
389
+
390
+
391
+ model = Linear(4, 2)
392
+ x = torch.randn(3, 4)
393
+ y = model(x)
394
+ ```
395
+
396
+ ---
397
+
398
+ ## License
399
+
400
+ OpenRath uses a BSD-style license; see [LICENSE](LICENSE) at the repository root.