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.
- openrath-1.0.0/.flake8 +9 -0
- openrath-1.0.0/.gitignore +21 -0
- openrath-1.0.0/.python-version +1 -0
- openrath-1.0.0/CONTRIBUTING.md +98 -0
- openrath-1.0.0/LICENSE +29 -0
- openrath-1.0.0/PKG-INFO +400 -0
- openrath-1.0.0/README.md +348 -0
- openrath-1.0.0/docs/Makefile +16 -0
- openrath-1.0.0/docs/make.bat +19 -0
- openrath-1.0.0/docs/source/_static/backend.png +0 -0
- openrath-1.0.0/docs/source/_static/logo.png +0 -0
- openrath-1.0.0/docs/source/_static/openrath.css +118 -0
- openrath-1.0.0/docs/source/_static/research_transformer.png +0 -0
- openrath-1.0.0/docs/source/_static/session.png +0 -0
- openrath-1.0.0/docs/source/_static/workflow.png +0 -0
- openrath-1.0.0/docs/source/_templates/.gitkeep +0 -0
- openrath-1.0.0/docs/source/conf.py +219 -0
- openrath-1.0.0/docs/source/developer_notes/agent_param.md +107 -0
- openrath-1.0.0/docs/source/developer_notes/index.md +53 -0
- openrath-1.0.0/docs/source/developer_notes/llm.md +125 -0
- openrath-1.0.0/docs/source/developer_notes/sandbox.md +125 -0
- openrath-1.0.0/docs/source/developer_notes/session.md +126 -0
- openrath-1.0.0/docs/source/developer_notes/tool.md +139 -0
- openrath-1.0.0/docs/source/developer_notes/workflow.md +132 -0
- openrath-1.0.0/docs/source/index.md +78 -0
- openrath-1.0.0/docs/source/install.md +237 -0
- openrath-1.0.0/docs/source/reference/backend.md +142 -0
- openrath-1.0.0/docs/source/reference/flow.md +68 -0
- openrath-1.0.0/docs/source/reference/flow_tool.md +88 -0
- openrath-1.0.0/docs/source/reference/index.md +36 -0
- openrath-1.0.0/docs/source/reference/llm.md +109 -0
- openrath-1.0.0/docs/source/reference/rath.md +28 -0
- openrath-1.0.0/docs/source/reference/session.md +130 -0
- openrath-1.0.0/docs/source/reference/utils.md +28 -0
- openrath-1.0.0/docs/source/showcase/architecture_story.md +53 -0
- openrath-1.0.0/docs/source/showcase/developer_quickstart.md +81 -0
- openrath-1.0.0/docs/source/showcase/docs_strategy.md +58 -0
- openrath-1.0.0/docs/source/showcase/index.md +32 -0
- openrath-1.0.0/docs/source/showcase/one_page_pitch.md +54 -0
- openrath-1.0.0/docs/source/showcase/pytorch_analogy.md +54 -0
- openrath-1.0.0/docs/source/showcase/session_lifecycle.md +57 -0
- openrath-1.0.0/docs/source/showcase/tools_sandbox_story.md +51 -0
- openrath-1.0.0/docs/source/showcase/website_homepage_draft.md +43 -0
- openrath-1.0.0/docs/source/tutorial/assets/custom-flow-tool/html/custom-flow-tool-01-define-custom-tool.html +85 -0
- openrath-1.0.0/docs/source/tutorial/assets/custom-flow-tool/html/custom-flow-tool-02-run-custom-tool-loop.html +98 -0
- openrath-1.0.0/docs/source/tutorial/assets/custom-flow-tool/logs/custom-flow-tool-01-define-custom-tool.txt +18 -0
- openrath-1.0.0/docs/source/tutorial/assets/custom-flow-tool/logs/custom-flow-tool-02-run-custom-tool-loop.txt +31 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-01-open-local-backend.html +82 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-02-write-workspace-file.html +72 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-03-run-shell-command.html +75 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-04-read-file-and-run-code.html +83 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/html/local-sandbox-tools-05-close-local-sandbox.html +73 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-01-open-local-backend.txt +15 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-02-write-workspace-file.txt +5 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-03-run-shell-command.txt +8 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-04-read-file-and-run-code.txt +16 -0
- openrath-1.0.0/docs/source/tutorial/assets/local-sandbox-tools/logs/local-sandbox-tools-05-close-local-sandbox.txt +6 -0
- openrath-1.0.0/docs/source/tutorial/assets/manifest.json +106 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-basics/html/session-basics-01-create-sessions.html +90 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-basics/html/session-basics-02-fork-and-detach.html +76 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-basics/html/session-basics-03-lazy-local-sandbox.html +74 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-basics/logs/session-basics-01-create-sessions.txt +23 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-basics/logs/session-basics-02-fork-and-detach.txt +9 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-basics/logs/session-basics-03-lazy-local-sandbox.txt +7 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/html/session-loop-tools-01-prepare-scripted-llm.html +73 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/html/session-loop-tools-02-run-session-loop.html +118 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/html/session-loop-tools-03-verify-loop-side-effect.html +75 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/logs/session-loop-tools-01-prepare-scripted-llm.txt +6 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/logs/session-loop-tools-02-run-session-loop.txt +51 -0
- openrath-1.0.0/docs/source/tutorial/assets/session-loop-tools/logs/session-loop-tools-03-verify-loop-side-effect.txt +8 -0
- openrath-1.0.0/docs/source/tutorial/custom_flow_tool.md +89 -0
- openrath-1.0.0/docs/source/tutorial/examples/custom_tool_usage.md +41 -0
- openrath-1.0.0/docs/source/tutorial/examples/engineering_agents.md +100 -0
- openrath-1.0.0/docs/source/tutorial/examples/index.md +28 -0
- openrath-1.0.0/docs/source/tutorial/examples/sandbox_backend_local.md +41 -0
- openrath-1.0.0/docs/source/tutorial/examples/sandbox_backend_opensandbox.md +43 -0
- openrath-1.0.0/docs/source/tutorial/examples/session_usage.md +51 -0
- openrath-1.0.0/docs/source/tutorial/examples/trading_agents.md +111 -0
- openrath-1.0.0/docs/source/tutorial/figures.md +42 -0
- openrath-1.0.0/docs/source/tutorial/index.md +41 -0
- openrath-1.0.0/docs/source/tutorial/local_sandbox_tools.md +80 -0
- openrath-1.0.0/docs/source/tutorial/scripts/run_tutorial_steps.py +635 -0
- openrath-1.0.0/docs/source/tutorial/session_basics.md +56 -0
- openrath-1.0.0/docs/source/tutorial/session_loop_tools.md +75 -0
- openrath-1.0.0/docs/source/user_guide/backends.md +112 -0
- openrath-1.0.0/docs/source/user_guide/concepts.md +30 -0
- openrath-1.0.0/docs/source/user_guide/index.md +28 -0
- openrath-1.0.0/docs/source/user_guide/llm.md +93 -0
- openrath-1.0.0/docs/source/user_guide/main_components.md +43 -0
- openrath-1.0.0/docs/source/user_guide/session.md +120 -0
- openrath-1.0.0/docs/source/user_guide/tools.md +114 -0
- openrath-1.0.0/docs/source/user_guide/workflow_agent.md +124 -0
- openrath-1.0.0/example/_chunk_print.py +17 -0
- openrath-1.0.0/example/_openai_provider.py +17 -0
- openrath-1.0.0/example/custom_tool_usage.py +91 -0
- openrath-1.0.0/example/engineering_agents/README.md +84 -0
- openrath-1.0.0/example/engineering_agents/agents.py +36 -0
- openrath-1.0.0/example/engineering_agents/main.py +68 -0
- openrath-1.0.0/example/engineering_agents/workflows.py +128 -0
- openrath-1.0.0/example/research_transformer/.gitignore +2 -0
- openrath-1.0.0/example/research_transformer/README.md +84 -0
- openrath-1.0.0/example/research_transformer/__init__.py +5 -0
- openrath-1.0.0/example/research_transformer/main.py +126 -0
- openrath-1.0.0/example/research_transformer/prompts.py +57 -0
- openrath-1.0.0/example/research_transformer/providers.py +75 -0
- openrath-1.0.0/example/research_transformer/tools.py +87 -0
- openrath-1.0.0/example/research_transformer/workflow.py +200 -0
- openrath-1.0.0/example/sandbox_backend_local.py +43 -0
- openrath-1.0.0/example/sandbox_backend_opensandbox.py +43 -0
- openrath-1.0.0/example/session_usage.py +36 -0
- openrath-1.0.0/example/trading_agents/README.md +67 -0
- openrath-1.0.0/example/trading_agents/_env.py +36 -0
- openrath-1.0.0/example/trading_agents/agents.py +44 -0
- openrath-1.0.0/example/trading_agents/main.py +69 -0
- openrath-1.0.0/example/trading_agents/tools.py +118 -0
- openrath-1.0.0/example/trading_agents/workflow.py +77 -0
- openrath-1.0.0/mypy.ini +12 -0
- openrath-1.0.0/pyproject.toml +50 -0
- openrath-1.0.0/pytest.ini +9 -0
- openrath-1.0.0/scripts/build_docs.bat +27 -0
- openrath-1.0.0/scripts/build_docs.sh +18 -0
- openrath-1.0.0/scripts/build_python_package.bat +20 -0
- openrath-1.0.0/scripts/build_python_package.sh +18 -0
- openrath-1.0.0/scripts/check_opensandbox.bat +63 -0
- openrath-1.0.0/scripts/check_opensandbox.sh +69 -0
- openrath-1.0.0/scripts/launch_opensandbox.bat +64 -0
- openrath-1.0.0/scripts/launch_opensandbox.sh +48 -0
- openrath-1.0.0/scripts/run_openrath_test.bat +43 -0
- openrath-1.0.0/scripts/run_openrath_test.sh +24 -0
- openrath-1.0.0/src/rath/__init__.py +26 -0
- openrath-1.0.0/src/rath/backend/__init__.py +87 -0
- openrath-1.0.0/src/rath/backend/abc.py +135 -0
- openrath-1.0.0/src/rath/backend/capabilities.py +31 -0
- openrath-1.0.0/src/rath/backend/dedicated_loop.py +61 -0
- openrath-1.0.0/src/rath/backend/errors.py +47 -0
- openrath-1.0.0/src/rath/backend/local.py +316 -0
- openrath-1.0.0/src/rath/backend/opensandbox.py +521 -0
- openrath-1.0.0/src/rath/backend/registry.py +95 -0
- openrath-1.0.0/src/rath/backend/results.py +100 -0
- openrath-1.0.0/src/rath/backend/stream.py +186 -0
- openrath-1.0.0/src/rath/backend/tool_types.py +73 -0
- openrath-1.0.0/src/rath/flow/__init__.py +16 -0
- openrath-1.0.0/src/rath/flow/agent.py +42 -0
- openrath-1.0.0/src/rath/flow/agent_param.py +56 -0
- openrath-1.0.0/src/rath/flow/compressor.py +35 -0
- openrath-1.0.0/src/rath/flow/tool/__init__.py +56 -0
- openrath-1.0.0/src/rath/flow/tool/base.py +33 -0
- openrath-1.0.0/src/rath/flow/tool/system_tool.py +173 -0
- openrath-1.0.0/src/rath/flow/tool/tool_table.py +43 -0
- openrath-1.0.0/src/rath/flow/workflow.py +73 -0
- openrath-1.0.0/src/rath/llm/__init__.py +39 -0
- openrath-1.0.0/src/rath/llm/chat_request.py +77 -0
- openrath-1.0.0/src/rath/llm/chat_response.py +95 -0
- openrath-1.0.0/src/rath/llm/client.py +42 -0
- openrath-1.0.0/src/rath/llm/openai_create_kwargs.py +130 -0
- openrath-1.0.0/src/rath/llm/openai_normalize.py +177 -0
- openrath-1.0.0/src/rath/llm/provider.py +58 -0
- openrath-1.0.0/src/rath/py.typed +0 -0
- openrath-1.0.0/src/rath/session/__init__.py +89 -0
- openrath-1.0.0/src/rath/session/chat_request_build.py +55 -0
- openrath-1.0.0/src/rath/session/chunk.py +178 -0
- openrath-1.0.0/src/rath/session/compress.py +139 -0
- openrath-1.0.0/src/rath/session/graph/__init__.py +44 -0
- openrath-1.0.0/src/rath/session/graph/kind.py +25 -0
- openrath-1.0.0/src/rath/session/graph/legacy.py +23 -0
- openrath-1.0.0/src/rath/session/graph/recording.py +115 -0
- openrath-1.0.0/src/rath/session/graph/traverse.py +136 -0
- openrath-1.0.0/src/rath/session/loop.py +382 -0
- openrath-1.0.0/src/rath/session/manager.py +44 -0
- openrath-1.0.0/src/rath/session/primitives.py +64 -0
- openrath-1.0.0/src/rath/session/provider_builtin.py +47 -0
- openrath-1.0.0/src/rath/session/session.py +295 -0
- openrath-1.0.0/src/rath/utils/__init__.py +28 -0
- openrath-1.0.0/src/rath/utils/decoding.py +38 -0
- openrath-1.0.0/src/rath/utils/env.py +52 -0
- openrath-1.0.0/tests/__init__.py +0 -0
- openrath-1.0.0/tests/backends/__init__.py +0 -0
- openrath-1.0.0/tests/backends/test_local.py +85 -0
- openrath-1.0.0/tests/backends/test_opensandbox.py +145 -0
- openrath-1.0.0/tests/conformance/__init__.py +0 -0
- openrath-1.0.0/tests/conformance/conftest.py +36 -0
- openrath-1.0.0/tests/conformance/test_cancellation.py +27 -0
- openrath-1.0.0/tests/conformance/test_code_run.py +30 -0
- openrath-1.0.0/tests/conformance/test_command_run.py +115 -0
- openrath-1.0.0/tests/conformance/test_concurrency.py +56 -0
- openrath-1.0.0/tests/conformance/test_files.py +69 -0
- openrath-1.0.0/tests/conformance/test_lifecycle.py +53 -0
- openrath-1.0.0/tests/conformance/test_stream_event.py +95 -0
- openrath-1.0.0/tests/conftest.py +34 -0
- openrath-1.0.0/tests/example/test_research_transformer_cli.py +182 -0
- openrath-1.0.0/tests/flow/test_flow_tool_user_subclass.py +104 -0
- openrath-1.0.0/tests/flow/test_workflow_agent.py +72 -0
- openrath-1.0.0/tests/integration/test_session_compress_real.py +180 -0
- openrath-1.0.0/tests/integration/test_session_loop_real.py +143 -0
- openrath-1.0.0/tests/llm/test_openai_chat_real.py +118 -0
- openrath-1.0.0/tests/openai_env_provider.py +17 -0
- openrath-1.0.0/tests/session/scripted_loop_executor.py +35 -0
- openrath-1.0.0/tests/session/test_chunk_messages.py +86 -0
- openrath-1.0.0/tests/session/test_lineage_graph_unit.py +105 -0
- openrath-1.0.0/tests/session/test_llm_message_wire.py +57 -0
- openrath-1.0.0/tests/session/test_run_session_loop_edges.py +354 -0
- openrath-1.0.0/tests/session/test_run_session_loop_local.py +222 -0
- openrath-1.0.0/tests/session/test_session_fork_detach_merge.py +43 -0
- openrath-1.0.0/tests/session/test_session_primitives.py +41 -0
- openrath-1.0.0/tests/session/test_session_registry.py +28 -0
- openrath-1.0.0/tests/session/test_session_sandbox_behavior.py +103 -0
- openrath-1.0.0/tests/session/test_tool_registry.py +99 -0
- openrath-1.0.0/tests/test_import.py +89 -0
- openrath-1.0.0/tests/unit/__init__.py +0 -0
- openrath-1.0.0/tests/unit/test_calls.py +106 -0
- openrath-1.0.0/tests/unit/test_capabilities.py +60 -0
- openrath-1.0.0/tests/unit/test_decoding.py +30 -0
- openrath-1.0.0/tests/unit/test_errors.py +58 -0
- openrath-1.0.0/tests/unit/test_flow_tool.py +67 -0
- openrath-1.0.0/tests/unit/test_opensandbox_bind_fallback.py +37 -0
- openrath-1.0.0/tests/unit/test_opensandbox_workspace_volume.py +47 -0
- openrath-1.0.0/tests/unit/test_registry.py +157 -0
- openrath-1.0.0/tests/unit/test_results.py +71 -0
- openrath-1.0.0/tests/unit/test_stream.py +199 -0
- openrath-1.0.0/uv.lock +1589 -0
openrath-1.0.0/.flake8
ADDED
|
@@ -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.
|
openrath-1.0.0/PKG-INFO
ADDED
|
@@ -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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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.
|