Metadata-Version: 2.4
Name: retriever-core
Version: 0.0.2
Summary: A Python programming model and runtime for closed-loop robot agents whose perception, planning, and control run at different rates.
Project-URL: Homepage, https://github.com/openretriever/retriever
Project-URL: Documentation, https://retriever.build/
Project-URL: Bug Tracker, https://github.com/openretriever/retriever/issues
Author: Linfeng Zhao
License: Apache-2.0
License-File: LICENSE
Keywords: bilevel-planning,foundation-models,planning,robotics,skill-learning,task-and-motion-planning
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Requires-Dist: packaging>=23
Provides-Extra: demo
Requires-Dist: matplotlib; extra == 'demo'
Requires-Dist: numpy; extra == 'demo'
Requires-Dist: opencv-python>=4.10; extra == 'demo'
Requires-Dist: pandas; extra == 'demo'
Requires-Dist: pynput; extra == 'demo'
Provides-Extra: dev
Requires-Dist: black; extra == 'dev'
Requires-Dist: lark; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pre-commit; extra == 'dev'
Requires-Dist: pygments; extra == 'dev'
Requires-Dist: pytest-asyncio; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=7.2.2; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Requires-Dist: typing-extensions; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocs>=1.6; extra == 'docs'
Requires-Dist: pymdown-extensions>=10; extra == 'docs'
Provides-Extra: dora
Requires-Dist: dora-rs-cli>=0.3.12; extra == 'dora'
Requires-Dist: dora-rs>=0.3.12; extra == 'dora'
Requires-Dist: psutil; extra == 'dora'
Requires-Dist: pyarrow; extra == 'dora'
Requires-Dist: pyyaml; extra == 'dora'
Provides-Extra: jax
Requires-Dist: flax; extra == 'jax'
Requires-Dist: jax; extra == 'jax'
Requires-Dist: jaxlib; extra == 'jax'
Requires-Dist: optax; extra == 'jax'
Provides-Extra: mcp
Requires-Dist: mcp<2,>=1.25.0; extra == 'mcp'
Provides-Extra: otel
Requires-Dist: opentelemetry-api; extra == 'otel'
Requires-Dist: opentelemetry-sdk; extra == 'otel'
Requires-Dist: uptrace; extra == 'otel'
Provides-Extra: recording
Requires-Dist: mcap>=1.0.0; extra == 'recording'
Requires-Dist: numpy; extra == 'recording'
Requires-Dist: rerun-sdk<0.24,>=0.21.0; extra == 'recording'
Provides-Extra: vision
Requires-Dist: pillow; extra == 'vision'
Requires-Dist: torch>=2.0.0; extra == 'vision'
Requires-Dist: transformers; extra == 'vision'
Provides-Extra: web
Requires-Dist: fastapi; extra == 'web'
Requires-Dist: uvicorn[standard]; extra == 'web'
Description-Content-Type: text/markdown

<div align="center">

<a href="https://openretriever.org/"><img width="200" height="auto" src="assets/retriever-illustrative.jpeg" alt="Retriever logo"></a>

<br>

<a href="https://openretriever.org/"><img src="assets/retriever-wordmark.svg" alt="Retriever" width="300"></a>

### Programming Closed-Loop Modular Robot Agents

<p>A Python programming model and runtime for robot agents whose perception, planning, and control run at different rates. You write down how often each part runs and how it handles data that arrives out of sync, so the timing lives in the graph instead of in hand-written glue code — and any run can be recorded and replayed exactly.</p>

<p>
  <a href="https://retriever.build/"><img alt="Docs" src="https://img.shields.io/badge/Docs-retriever.build-0f766e?style=for-the-badge"></a>
  <a href="https://openretriever.org/"><img alt="Website" src="https://img.shields.io/badge/Website-openretriever.org-111827?style=for-the-badge"></a>
  <a href="https://discord.gg/V79H7TwwNg"><img alt="Discord" src="https://img.shields.io/badge/Discord-join-5865F2?style=for-the-badge&logo=discord&logoColor=white"></a>
  <br>
  <a href="https://golden.retriever.build/examples/"><img alt="GoldenRetriever examples" src="https://img.shields.io/badge/GoldenRetriever-examples-f97316?style=for-the-badge"></a>
  <a href="https://retriever.build/ecosystem/"><img alt="Hub packs" src="https://img.shields.io/badge/Retriever_Hub-packs-9333ea?style=for-the-badge"></a>
  <a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/License-Apache_2.0-3b82f6?style=for-the-badge"></a>
</p>

</div>

---

Robot systems rarely run as one neat synchronous loop: cameras, estimators, planners, VLMs, VLAs, and controllers all update at different rates. **Retriever** lets you declare how often each `Flow` runs and how each edge samples data — so the timing lives in the graph, not in glue code. Step the same graph in-process to debug, or run it on a backend to deploy; every run records and replays exactly.

## See it run

One line, on any laptop with a webcam:

```bash
pip install "retriever-core[demo]" rerun-sdk
retriever demo webcam --visualize rerun
```

This pulls the [`openretriever/webcam-demo`](https://github.com/openretriever/webcam-demo) Hub pack (no clone) and drives a live `Camera → ColorDetector → Rerun` closed loop with bounding-box overlays. Full walkthrough: **[retriever.build](https://retriever.build/)**.

## Install

```bash
python -m pip install retriever-core     # runtime + `retriever` CLI; imports as `retriever`
```

Python 3.11+. For the bundled demos, renderers, and tests, use a source checkout: `git clone https://github.com/openretriever/retriever && cd retriever && retriever install`.

## Quickstart

```python
from retriever import Flow, Latest, Pipeline, Rate, Trigger, io


@io
class Number:
    value: int


@io
class Doubled:
    value: int


class Source(Flow[None, Number]):
    def __init__(self) -> None:
        super().__init__()
        self.count = 0

    def step(self, _):
        self.count += 1
        return Number(value=self.count)


class Double(Flow[Number, Doubled]):
    def step(self, input: Number) -> Doubled:
        return Doubled(value=input.value * 2)


pipe = Pipeline("quickstart")
with pipe:
    source = Source() @ Rate(hz=2)          # runs at 2 Hz
    double = Double() @ Trigger("value")    # wakes on each Number
    source.then(double, sync=Latest())      # edge samples the latest value

pipe.run(backend="multiprocessing", duration=1.0)   # deploy
# result = pipe.step(dt=0.1)                         # ...or step in-process to debug + replay
```

`@io` typed message · `Flow[I, O]` node logic · `flow @ clock` when it runs · `.then(…, sync=…)` how the edge samples · `pipe.run()` to deploy, `pipe.step()` to debug and replay.

## Learn more

| Guide | What's there |
| --- | --- |
| **[Docs home](https://retriever.build/)** | install, visual quickstart, tutorials |
| **[Concepts](https://retriever.build/concepts/)** | Flow, clocks, sync policies, IR, record/replay |
| **[Retriever Hub](https://retriever.build/ecosystem/)** | load packs by name from any repo — no clone |
| **[GoldenRetriever](https://golden.retriever.build/examples/)** | applied robot examples: perception, memory, language, sim |
| **[Discord](https://discord.gg/V79H7TwwNg)** | questions, help, and community |

<details>
<summary><b>In-process stepping, record &amp; replay</b></summary>

Retriever has two execution modes on purpose. Backend execution is for realistic scheduling and deployment; in-process stepping is for debugging logic, replaying incidents, and making timing bugs inspectable with normal Python tools.

```python
# Backend execution — realistic scheduling, process boundaries, deployment
pipe.run(backend="multiprocessing", duration=3.0)
pipe.run(backend="dora", duration=3.0)

# In-process debugging — step the graph, inspect, checkpoint, replay
result = pipe.step(dt=0.1)
print(result.executed)
pipe.close_stepper()
```

The same timestamped input trace yields the same output trace regardless of backend — that determinism is what makes local stepping, record, and replay well-defined. See [Debug and Visualize](https://retriever.build/tutorials/debug-and-visualize/).

</details>

<details>
<summary><b>Ecosystem boundary</b></summary>

- **Core runtime** — this repo, published as `retriever-core`, imported as `retriever`. Stays focused on the runtime.
- **[GoldenRetriever](https://golden.retriever.build/examples/)** — the applied examples + Hub-pack layer (robot payloads, simulator/visualization lanes). Built on the runtime, not a second one.
- **Retriever Hub** — the manifest + index protocol that turns any repo into a loadable pack of Flows, types, and pipelines.
- **[openretriever.org](https://openretriever.org/)** — the project home.

</details>

<details>
<summary><b>Contributing &amp; development</b></summary>

Contributor tasks run through the same `retriever` command from a source checkout:

```bash
retriever install                     # set up the environment
retriever run test                    # full test suite
retriever run p0-release-readiness
retriever run public-surface-check    # external launch check
```

The source checkout uses [Pixi](https://pixi.sh) as its environment/task backend, and `retriever run <task>` wraps it. `main` is canonical — a fresh clone and ordinary `git pull` fast-forward. See [docs/contributing.md](docs/contributing.md).

</details>

## Community &amp; license

Questions and help: **[Discord](https://discord.gg/V79H7TwwNg)**. Licensed under Apache-2.0 — see [LICENSE](LICENSE) and [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
