add dora-node.yml manifest and a service example dataflow

The manifest is the only contract a consumer has, since no source package
is shared between node repositories, and dora validate checks a dataflow
against it without running the node — so CI needs no robot.

request and response are deliberately untyped. They carry request_id, and
dora defines that as the marker for a pattern-correlated port where
several Arrow schemas legitimately flow, one per service; the runtime
skips type checks on those messages, so annotating them would claim a
contract neither side keeps.

examples/ carries its own manifest because dora resolves a node's
manifest by walking up from its path, and a manifest applies only when
<manifest dir>/<entrypoint> names the same file as the dataflow's path.
Without it the example caller would be matched against the arm node's
manifest and strict validation would fail on the entrypoint mismatch.
This commit is contained in:
2026-09-12 11:47:06 -03:00
parent fdabf7e241
commit a2bf59065d
4 changed files with 250 additions and 10 deletions
+28 -10
View File
@@ -1,19 +1,37 @@
# The repository's own example: builds and runs the node from this checkout, so
# `dora validate` picks up the typed contract in dora-node.yml next to it.
# A consumer wires the node from a tag instead — see README.md.
#
# Run it with `--uv` so every Python node gets its own managed environment.
#
# `examples/caller.py` shows the whole convention: a non-blocking motion
# answered at once, its progress followed on `motion_state`, and a second motion
# preempting the first.
strict_types: true
nodes:
- id: ulite6
build: uv pip install -e .
path: dora_ulite6/main.py
path: dora-ulite6
build: pip install .
inputs:
tick: dora/timer/millis/10
tick: dora/timer/millis/100
request: caller/request
outputs:
- status
- response
- motion_state
- joint_pose
- tcp_pose
- robot_state
env:
ROBOT_IP: "192.168.1.192"
DEFAULT_SPEED: "30"
DEFAULT_UNITS: "mm"
API_HOST: "0.0.0.0"
API_PORT: "9000"
VACUUM_ENABLED: "true"
TOOL_TYPE: "vacuum"
TOOL_OFFSET_MM: "0.0"
INIT_MODE: "none"
- id: caller
path: examples/caller.py
inputs:
tick: dora/timer/millis/500
response: ulite6/response
motion_state: ulite6/motion_state
outputs:
- request