Installation#
OpenRath supports CPython 3.10 through 3.13. Choose the installation path that matches your use case:
Goal |
Path |
|---|---|
Use the v2 durable Runtime and Agent Server |
|
Use the v1-compatible façade published on PyPI |
|
Route chat through LiteLLM providers |
|
Modify OpenRath source, run tests, or build docs |
|
Use persistent memory |
|
Use a container sandbox backend |
|
Use OpenViking memory |
Install Stable v2.0.0 from the GitHub release#
Install the exact Stable 2.0.0 release wheel:
python -m pip install \
"openrath @ https://github.com/Rath-Team/OpenRath/releases/download/v2.0.0/openrath-2.0.0-py3-none-any.whl"
For the Agent Server with PostgreSQL:
python -m pip install \
"openrath[server,postgres] @ https://github.com/Rath-Team/OpenRath/releases/download/v2.0.0/openrath-2.0.0-py3-none-any.whl"
Continue with the v2 quickstart. For service deployments, follow the operations guide.
Install the v1-compatible package from PyPI#
The durable v2 Runtime is distributed through the exact 2.0.0 release asset
above. The PyPI path installs the retained v1-compatible façade: Session,
Workflow, FlowToolCall, the local backend, local memory, OpenAI-compatible
and Anthropic LLM clients, persistent config, and the stdio MCP adapter.
LiteLLM is optional.
pip install "openrath==1.3.0"
If you manage your project environment with uv:
uv add "openrath==1.3.0"
Core dependencies include:
Dependency |
Purpose |
|---|---|
|
OpenAI-compatible chat client and Azure OpenAI routing. |
|
Anthropic Messages API adapter. |
|
Stdio MCP server integration. |
|
Tool schemas, request/response models, and configuration types. |
Install the LiteLLM extra#
OpenRath v2.0.0 can route chat calls through LiteLLM when its optional extra is installed:
python -m pip install \
"openrath[litellm] @ https://github.com/Rath-Team/OpenRath/releases/download/v2.0.0/openrath-2.0.0-py3-none-any.whl"
For the v1-compatible PyPI package, use
pip install "openrath[litellm]==1.3.0".
from rath.llm import Provider, chat_client_for
provider = Provider(
provider_kind="litellm",
model="gemini/gemini-2.0-flash",
)
client = chat_client_for(provider)
Without the extra, the LiteLLM adapter is not registered and selecting
provider_kind="litellm" raises an unknown-provider error.
Configure the LLM#
Real LLM workflows require provider configuration. The most explicit path is to build a Provider with the API key, optional base URL, model, and provider kind. Clients resolve credentials in this order:
Provider(...)fields.Environment variables.
The OpenRath config store (
config.jsonpluscredentials.json).
export OPENAI_API_KEY=...
export OPENAI_BASE_URL=https://api.openai.com/v1
export OPENAI_DEFAULT_MODEL=gpt-5.5
export ANTHROPIC_API_KEY=...
export ANTHROPIC_DEFAULT_MODEL=claude-sonnet-4-5
export LITELLM_API_KEY=...
export LITELLM_API_BASE=...
export LITELLM_MODEL=gemini/gemini-2.0-flash
Variable |
Meaning |
|---|---|
|
OpenAI or compatible gateway API key. The default client fails if this is missing. |
|
OpenAI-compatible endpoint. |
|
OpenAI-compatible fallback model. |
|
Azure OpenAI endpoint fallback when |
|
Azure OpenAI key fallbacks. |
|
Legacy Azure API version; default is |
|
Anthropic API key. |
|
Optional Anthropic-compatible endpoint. |
|
Anthropic fallback model. |
|
Generic LiteLLM key fallback; provider-specific variables may instead be resolved by LiteLLM. |
|
Optional LiteLLM API-base override. |
|
Model fallback when |
Persistent config is JSON:
{
"version": 1,
"llm": {
"default_provider": "openai-main",
"providers": {
"openai-main": {
"provider_kind": "openai",
"model": "gpt-5.5"
}
}
},
"memory": {
"default_provider": "local-main",
"providers": {
"local-main": {
"backend_kind": "local",
"path": ".openrath/memory",
"embedding_provider": "openai-main",
"chat_provider": "openai-main"
}
}
}
}
Store the key in the sibling credentials file:
{
"version": 1,
"llm": {
"providers": {
"openai-main": "sk-..."
}
}
}
The v1-compatible config loader included in v2.0.0 still loads an inline
api_key from legacy config.json; the next ConfigStore.save() migrates it
to credentials.json (mode 0600 on POSIX).
When a save rewrites a non-empty credentials payload, keys set to None are
omitted. If the resulting payload is empty, however, the loader leaves an
existing sidecar untouched; remove that file or entry explicitly when revoking
the last stored credential.
Use it from Python:
from rath.llm import Provider
provider = Provider.from_config("openai-main", temperature=0.2)
OpenRath does not auto-load .env files. Source them in the shell or let your deployment platform inject secrets before starting Python.
For a named LiteLLM provider, use the normal JSON config schema and construct
the provider explicitly through Provider.from_config(...):
{
"version": 1,
"llm": {
"default_provider": "gemini",
"providers": {
"gemini": {
"provider_kind": "litellm",
"model": "gemini/gemini-2.0-flash"
}
}
}
}
provider = Provider.from_config("gemini")
The LiteLLM client does not scan OpenRath config on its own.
If you also cloned the OpenRath repository, you can first run examples that do not depend on OpenSandbox or a live model:
python example/02_session_lineage.py
python example/06_mcp_tool.py
python example/09_memory.py
When using OpenRath from PyPI in your own project, import it directly:
import os
from rath import flow
from rath.llm import Provider
from rath.session import Session
provider = Provider(
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.environ.get("OPENAI_BASE_URL") or None,
model=os.environ.get("OPENAI_DEFAULT_MODEL") or "gpt-5.5",
)
agent = flow.Agent("Use tools when helpful.", provider=provider)
user = Session.from_user_message("List files.").to("local", spec=".")
out = agent(user)
Configure Memory#
The v1-compatible memory API included in OpenRath v2.0.0 provides local memory
in the base install. The local backend is registered as local, uses public
memory:// URIs, stores data under .openrath/memory/ by default, and can run
lexical BM25 recall without any LLM key.
The shortest path is:
from rath import flow
with flow.Agent("Remember useful facts.", model="demo", memory="local") as agent:
agent.remember_memory("The user writes Python.")
hits = agent.recall_memory("preferred programming language")
Configure named local memory stores in ~/.openrath/config.json:
{
"version": 1,
"memory": {
"default_provider": "local-main",
"providers": {
"local-main": {
"backend_kind": "local",
"path": ".openrath/memory",
"embedding_provider": "embed-main",
"chat_provider": "chat-main"
}
}
}
}
Field |
Meaning |
|---|---|
|
Currently |
|
Local memory root. Relative paths are resolved from the current project. |
|
Optional |
|
Optional |
Run the key-free memory example from a source checkout:
python example/09_memory.py
Install from source for development#
This is the developer installation path. Use it to modify OpenRath source, run tests, build docs, or debug examples.
git clone https://github.com/Rath-Team/OpenRath.git
cd OpenRath
uv sync --group dev --group docs
Without uv, use an editable install. This also works in an existing mamba/conda environment:
pip install -e .
pip install pytest ruff mypy sphinx myst-parser pydata-sphinx-theme
Development dependencies include:
Dependency group |
Contents |
|---|---|
runtime |
|
optional |
LiteLLM chat adapter and provider integrations. |
dev |
|
docs |
|
Configure credentials in your shell, CI secret store, or deployment environment. OpenRath does not load repository-local secret files.
Run tests:
bash scripts/run_openrath_test.sh
Build the docs:
bash scripts/build_docs.sh
Or call Sphinx directly:
uv run sphinx-build -M html docs/source docs/_build
In a mamba environment that already has the docs dependencies installed, the equivalent direct build is:
mamba run -n rath-dev python -m sphinx -M html docs/source docs/_build
The generated output is under docs/_build/html/.
Launch and connect OpenSandbox#
OpenSandbox is an optional backend. It is useful for workflows that need a container execution environment. OpenRath connects to it with Session.to("opensandbox", spec=...); the default local backend does not require this step.
The v1-compatible OpenSandbox backend included in v2.0.0 defaults to
opensandbox/code-interpreter:v1.1.0 with entrypoint
/opt/code-interpreter/code-interpreter.sh. Override both through
BackendSandboxSpec only when your deployment supplies another compatible
image.
Install the OpenSandbox extra#
When using PyPI:
pip install "openrath[opensandbox]"
When using a source development environment:
uv sync --extra opensandbox
This extra installs:
Package |
Purpose |
|---|---|
|
OpenSandbox Python SDK. |
|
Code interpreter client. |
|
Starts the OpenSandbox API server locally. |
Start the service#
Local development usually starts OpenSandbox with the repository script. The script checks Docker, syncs the optional dependency, generates .sandbox.toml, adds the current OpenRath project directory to the host bind allowlist, and starts opensandbox-server. On macOS with Colima, if DOCKER_HOST is unset and the Colima socket exists, the script exports DOCKER_HOST=unix://${HOME}/.colima/default/docker.sock automatically.
macOS / Linux:
bash scripts/launch_opensandbox.sh
Windows:
scripts\launch_opensandbox.bat
The script uses the OpenSandbox Docker configuration example by default. Switch the packaged example with an environment variable:
SANDBOX_INIT_EXAMPLE=docker bash scripts/launch_opensandbox.sh
Allowed values include docker, docker-zh, k8s, and k8s-zh.
Check service status#
After the OpenSandbox server starts, first check that the control plane responds. /health is the unauthenticated health-check path for the OpenSandbox server.
curl -fsS http://127.0.0.1:8080/health
If curl is not installed, use Python for the same check:
python - <<'PY'
import urllib.request
with urllib.request.urlopen("http://127.0.0.1:8080/health", timeout=3) as resp:
print(resp.status)
print(resp.read().decode("utf-8", errors="replace"))
PY
The health check only confirms that the OpenSandbox API server responds locally. The container runtime, workspace bind, and OpenRath client configuration still need to be verified with the later example.
Connect OpenRath to OpenSandbox#
Set client variables in the environment where OpenRath runs:
export OPEN_SANDBOX_DOMAIN=127.0.0.1:8080
export OPEN_SANDBOX_API_KEY=
If the server sets an API key, the server and client values must match:
export OPENSANDBOX_SERVER_API_KEY=...
export OPEN_SANDBOX_API_KEY=...
Variable |
Meaning |
|---|---|
|
OpenSandbox API server address. The local default is |
|
API key used by the OpenRath client when requesting the server. |
|
API key on the OpenSandbox server side. |
|
When set to |
In the v1-compatible configuration surface included in v2.0.0, the backend
domain is used for availability resolution and is not injected into the SDK
connection; backend api_key also has no runtime consumer. Keep the environment
variables above or configure the SDK through ~/.sandbox.toml for an actual
connection.
Verify the backend#
After confirming that the server is listening locally, run the sandbox backend example:
python example/03_sandbox_backend.py opensandbox
You can also bind directly in Python:
from rath.session import Session
user = Session.from_user_message("List the workspace.")
user = user.to("opensandbox", spec=".")
spec="." requests a bind from the current directory to /workspace inside the container. This host path must be visible to the machine running the OpenSandbox server and allowed by the storage allowlist in .sandbox.toml. The repository script automatically allowlists the current project directory. To bind other directories, manually add the matching prefix to allowed_host_paths. If the host bind is rejected, OpenRath retries with an empty workspace by default. Set RATH_OPENSANDBOX_STRICT_WORKSPACE_BIND=1 to disable this fallback.
Local sandbox path notes#
Session.to("local", spec="...") treats the string spec as BackendSandboxSpec(working_dir=...). LocalBackend.close(...) only deletes temporary working directories that OpenRath created itself. User-supplied working directories are left on disk when the sandbox closes.
Launch and connect OpenViking#
OpenViking is an optional memory backend. The base local memory backend does not require it.
Install the extra:
pip install "openrath[openviking]"
When developing from source, use the repository scripts:
bash scripts/launch_openviking.sh
bash scripts/check_openviking.sh
OpenViking exposes a richer external memory service. OpenRath keeps the public memory API on memory:// URIs; the adapter translates to OpenViking’s internal viking:// boundary.