Small FastAPI mission router and recovery layer for mixed intralogistics. This service is intentionally limited to orchestration, assignment, and recovery. It does not do navigation, path planning, or fleet optimization.
HaulOS is a minimal mission router for warehouse handoff flows such as receiving -> buffer and receiving -> line. It sits between job creation systems and heterogeneous execution agents, then applies explicit policy checks before assigning work.
The current MVP supports:
- AMR and forklift agent types
- in-memory mission state
- capability-aware and zone-aware assignment
- deterministic routing decisions
- structured event logging for assignments, rejections, and failures
- mission requeue when an assigned agent fails
The goal is to model the orchestration layer cleanly without hiding the core routing decisions behind vendor SDKs or optimization engines. That keeps the codebase small, testable, and useful as a reference implementation for mission lifecycle handling.
- Python 3.11
- FastAPI
- Pydantic
- pytest
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
uvicorn haulos.main:app --reloadRegister one AMR:
curl -X POST http://127.0.0.1:8000/agents \
-H 'content-type: application/json' \
-d '{
"agent_id": "amr-1",
"agent_type": "amr",
"capabilities": ["tow"],
"zones": ["receiving", "buffer"],
"payload_kg": 300,
"battery_pct": 88,
"current_zone": "receiving"
}'Register one forklift:
curl -X POST http://127.0.0.1:8000/agents \
-H 'content-type: application/json' \
-d '{
"agent_id": "forklift-1",
"agent_type": "forklift",
"capabilities": ["lift"],
"zones": ["receiving", "line"],
"payload_kg": 1200,
"battery_pct": 75,
"current_zone": "receiving"
}'Submit two missions:
curl -X POST http://127.0.0.1:8000/missions \
-H 'content-type: application/json' \
-d '{
"mission_id": "mission-1",
"source": "receiving",
"destination": "buffer",
"load_type": "pallet",
"priority": 10,
"required_capabilities": ["tow"],
"allowed_zones": ["receiving", "buffer"],
"min_payload_kg": 100
}'curl -X POST http://127.0.0.1:8000/missions \
-H 'content-type: application/json' \
-d '{
"mission_id": "mission-2",
"source": "receiving",
"destination": "line",
"load_type": "pallet",
"priority": 20,
"required_capabilities": ["lift"],
"allowed_zones": ["receiving", "line"],
"min_payload_kg": 500
}'Advance the router by one assignment:
curl -X POST http://127.0.0.1:8000/router/stepInspect state and event log:
curl http://127.0.0.1:8000/state
curl http://127.0.0.1:8000/eventsSimulate an agent failure and recover:
curl -X POST http://127.0.0.1:8000/agents/forklift-1/fail
curl -X POST http://127.0.0.1:8000/agents/forklift-1/recover- State is in memory only.
- The event log is append-only for the life of the process.
POST /router/stepassigns at most one mission per call.- The router is intentionally deterministic so assignment behavior is easy to test and explain.
- This repo focuses on orchestration and recovery, not navigation or fleet optimization.
- Add a clearer sample event timeline to the demo section.
- Add a simple persisted storage option with SQLite for restart-safe state.
- Expand mission lifecycle examples for
start,complete,fail, andrecover. - Add CI so tests and packaging checks run automatically on push.
This project is licensed under the MIT License. See LICENSE.
