Standard Types
What you’ll learn: where the shared robot payload types live (retriever.types.*), that each is already an @io type you can drop straight onto a Flow port, and why type identity — not just field shape — is the contract.
There is one canonical home for standard payloads: retriever.types, shipped with the runtime. Anything that runs Retriever — examples, Hub modules, GoldenRetriever — imports these classes directly, so two components that both say PoseStamped mean the same class, not two look-alikes.
The canonical modules
Section titled “The canonical modules”| Module | Types it exports |
|---|---|
retriever.types.spatial |
Header, Vector3, Quaternion, SE3Pose, PoseStamped, Twist/TwistStamped, Wrench/WrenchStamped, JointState (+ validate_*) |
retriever.types.perception |
Image2D, CompressedImage2D, EncodedVideo, CameraIntrinsics, PointCloud3D, BBox2D, Detection2D, DetectionBatch, SegmentationMask2D, PointTarget2D (+ validate_*) |
retriever.types.language |
TextSpan, Caption, Prompt, ReferringExpression, GroundedPhrase, PlanStepText, PlanText (+ validate_*) |
retriever.types.symbolic |
Object, ObjectType, Variable, Predicate, LiftedAtom, GroundAtom, State, Action, Option, ParameterizedOption, Task, SkillSignature, GroundedSkill |
retriever.types.data |
Event, EventBuffer, MultiStreamBuffer, DataSpec, StreamSpec, JoinPolicy, WindowPolicy, DatasetManifest, EpisodeManifest, LineageRef |
retriever.types (root) |
StreamId, SchemaRef, ClockDomain — stream identity and schema primitives |
Use them directly as Flow ports
Section titled “Use them directly as Flow ports”Every payload class is already @io-decorated, so it can be a Flow input or output with no wrapping:
SE3Pose, PoseStamped, Twist, and Wrench are composed from Vector3/Quaternion/Header, so nested access (pose.pose.position.x) works as written. Where an invariant exists, a matching validate_* helper enforces it — e.g. validate_quaternion checks unit norm.
How the ecosystem refers to them
Section titled “How the ecosystem refers to them”- Hub modules depend on
retriever-coreand importretriever.types.*in their port contracts. Never vendor a copy — a copied class with the same name is a different type at runtime. - GoldenRetriever imports the canonical runtime types directly and adds what the runtime should not own: Arrow conversions and higher-level robotics/planning payloads, published as a Hub-loadable applied pack.
- Extension packs publish domain-specific type sets as Hub modules loaded with
hub.use("org/types-pack:SomeType")— built on top of the standard modules, never instead of them.
Applied payloads such as WorldState, BeliefGraph, Skill, Plan, and Trajectory deliberately live in GoldenRetriever or other Hub packs, so they can evolve with domain semantics without expanding the core runtime API.
Rules of thumb
Section titled “Rules of thumb”- Need a common robotics payload? Import it from
retriever.types.*. - Adding a broadly useful payload? Contribute it to
retriever.types— versioned,@io-decorated, with validators where invariants exist. - Adding a niche or heavy payload? Keep it in your own module, typed with standard fields (
Header,SchemaRef) so it composes. - Never redefine a standard type locally, even with identical fields — type identity is the contract.
For Hub-distributed applied types, the cross-version contract is the registered schema and serialization behavior, not Python class identity across unrelated versions. Pin one Hub ref per application, and compose runtime standard types rather than redefining them.
