refactor(config): resolve config type from annotation#1751
refactor(config): resolve config type from annotation#1751
Conversation
2cfbda9 to
9c8caef
Compare
There was a problem hiding this comment.
Pull request overview
This PR refactors how Configurable classes determine their config type across DimOS, shifting from Generic/default_config patterns to resolving the config model via the config: ... type annotation. It updates many modules/services accordingly and introduces a new memory2 module helper.
Changes:
- Replace Generic-based config resolution (
default_config/Parent[MyConfig]) with annotation-based resolution usingget_type_hints(...)[“config”]. - Update a large set of modules/services to remove
default_configand declareconfig: <ConfigModel>directly. - Simplify RPC client/timeout initialization defaults and add a new
memory2StreamModule/Recorder module file.
Reviewed changes
Copilot reviewed 90 out of 90 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| dimos/web/websocket_vis/websocket_vis_module.py | Remove Module[Config] inheritance; add config: annotation. |
| dimos/visualization/rerun/bridge.py | Remove Module[Config] inheritance; add config: annotation. |
| dimos/utils/cli/lcmspy/lcmspy.py | Remove generic service base; add config: annotations. |
| dimos/teleop/quest/quest_teleop_module.py | Drop Module[_Config]; switch to config: annotation. |
| dimos/teleop/quest/quest_extensions.py | Drop generic base usage; add config: annotations. |
| dimos/teleop/phone/phone_teleop_module.py | Remove Module[Config]; add config: annotation. |
| dimos/teleop/keyboard/keyboard_teleop_module.py | Remove Module[Config]; add config: annotation. |
| dimos/simulation/unity/module.py | Remove Module[Config]; add config: annotation. |
| dimos/robot/unitree/type/map.py | Remove Module[Config]; add config: annotation. |
| dimos/robot/unitree/go2/fleet_connection.py | Remove default_config; (intended) align with annotation-based config. |
| dimos/robot/unitree/go2/connection.py | Remove generic Module[_Config]; introduce annotation-based config. |
| dimos/robot/unitree/g1/sim.py | Remove default_config; (intended) align with annotation-based config. |
| dimos/robot/unitree/g1/connection.py | Remove generic Module[_Config]; introduce config: annotation. |
| dimos/robot/unitree/b1/connection.py | Remove Module[Config]; add config: annotation. |
| dimos/robot/foxglove_bridge.py | Remove default_config; add config: annotation. |
| dimos/robot/drone/connection_module.py | Remove Module[Config]; add config: annotation. |
| dimos/protocol/tf/tflcmcpp.py | Remove generic bases; add config: annotation. |
| dimos/protocol/tf/tf.py | Remove generic TF spec/config plumbing; add concrete config: annotations. |
| dimos/protocol/service/test_spec.py | Update tests to validate new config-type resolution behavior. |
| dimos/protocol/service/spec.py | Implement config resolution via get_type_hints(type(self))[“config”]. |
| dimos/protocol/service/lcmservice.py | Remove generic config TypeVar usage; add config: annotation. |
| dimos/protocol/service/ddsservice.py | Remove generic base usage; add config: annotation. |
| dimos/protocol/rpc/pubsubrpc.py | Provide default timeout args via constants; simplify call sites. |
| dimos/protocol/pubsub/impl/redispubsub.py | Remove generic Service[Config]; add config: annotation. |
| dimos/protocol/pubsub/bridge.py | Remove generic Service[...]; add parameterized config: annotation. |
| dimos/perception/test_spatial_memory_module.py | Remove Module[Config]; add config: annotation. |
| dimos/perception/spatial_perception.py | Remove Module[Config]; add config: annotation. |
| dimos/perception/object_tracker.py | Remove default_config; add config: annotation. |
| dimos/perception/object_tracker_2d.py | Remove default_config; add config: annotation. |
| dimos/perception/experimental/temporal_memory/temporal_memory.py | Remove Module[Config]; add config: annotation. |
| dimos/perception/detection/reid/module.py | Remove default_config; (intended) align with annotation-based config. |
| dimos/perception/detection/module2D.py | Remove Module[Config]; add config: annotation. |
| dimos/navigation/rosnav.py | Remove Module[Config]; add config: annotation. |
| dimos/navigation/frontier_exploration/wavefront_frontier_goal_selector.py | Remove Module[Config]; add config: annotation. |
| dimos/navigation/bbox_navigation.py | Remove Module[Config]; add config: annotation. |
| dimos/models/vl/qwen.py | Remove default_config; (intended) align with annotation-based config. |
| dimos/models/vl/openai.py | Remove default_config; (intended) align with annotation-based config. |
| dimos/models/vl/moondream.py | Remove default_config; (intended) align with annotation-based config. |
| dimos/models/vl/moondream_hosted.py | Remove default_config; (intended) align with annotation-based config. |
| dimos/models/vl/base.py | Remove generic config TypeVar; make VlModel Configurable-based. |
| dimos/models/embedding/treid.py | Remove default_config; retain config: annotation. |
| dimos/models/embedding/mobileclip.py | Remove default_config; retain config: annotation. |
| dimos/models/embedding/clip.py | Remove default_config; retain config: annotation. |
| dimos/models/base.py | Remove generic Configurable[...] usage; rely on config: annotation. |
| dimos/memory2/vectorstore/sqlite.py | Remove default_config; retain config: annotation. |
| dimos/memory2/vectorstore/memory.py | Replace default_config with config: annotation. |
| dimos/memory2/vectorstore/base.py | Remove generic Configurable[...]; add config: annotation. |
| dimos/memory2/store/sqlite.py | Remove default_config; retain config: annotation. |
| dimos/memory2/store/base.py | Remove generic Configurable[...]; add config: annotation. |
| dimos/memory2/registry.py | Remove generic Configurable[...]; add config: annotation. |
| dimos/memory2/observationstore/sqlite.py | Remove default_config; retain config: annotation. |
| dimos/memory2/observationstore/memory.py | Remove default_config; retain config: annotation. |
| dimos/memory2/observationstore/base.py | Remove generic Configurable[...]; add config: annotation. |
| dimos/memory2/notifier/subject.py | Replace default_config with config: annotation. |
| dimos/memory2/notifier/base.py | Remove generic Configurable[...]; add config: annotation. |
| dimos/memory2/module.py | Add StreamModule/Recorder helpers for memory2 pipelines/recording. |
| dimos/memory2/blobstore/sqlite.py | Remove default_config; retain config: annotation. |
| dimos/memory2/blobstore/file.py | Remove default_config; retain config: annotation. |
| dimos/memory2/blobstore/base.py | Remove generic Configurable[...]; add config: annotation. |
| dimos/memory/embedding.py | Remove Module[Config]; add config: annotation. |
| dimos/mapping/voxels.py | Remove Module[Config]; add config: annotation. |
| dimos/mapping/costmapper.py | Remove Module[Config]; add config: annotation. |
| dimos/manipulation/pick_and_place_module.py | Remove default_config; keep config: annotation. |
| dimos/manipulation/manipulation_module.py | Remove Module[Config]; add config: annotation. |
| dimos/manipulation/grasping/graspgen_module.py | Remove Module[Config]; add config: annotation. |
| dimos/manipulation/control/trajectory_controller/joint_trajectory_controller.py | Remove Module[Config]; add config: annotation. |
| dimos/manipulation/control/servo_control/cartesian_motion_controller.py | Remove Module[Config]; add config: annotation. |
| dimos/hardware/sensors/lidar/livox/module.py | Remove generic base usage; add config: annotation. |
| dimos/hardware/sensors/lidar/fastlio2/module.py | Remove generic base usage; add config: annotation. |
| dimos/hardware/sensors/fake_zed_module.py | Remove Module[Config]; add config: annotation. |
| dimos/hardware/sensors/camera/zed/camera.py | Remove Module[Config]; add config: annotation. |
| dimos/hardware/sensors/camera/webcam.py | Remove default_config; (intended) align with annotation-based config. |
| dimos/hardware/sensors/camera/spec.py | Remove TypeVar generic config plumbing; make CameraHardware Configurable. |
| dimos/hardware/sensors/camera/realsense/camera.py | Remove Module[Config]; add config: annotation. |
| dimos/hardware/sensors/camera/module.py | Remove Module[Config]; add config: annotation. |
| dimos/hardware/sensors/camera/gstreamer/gstreamer_camera.py | Remove Module[Config]; add config: annotation. |
| dimos/experimental/security_demo/security_module.py | Remove Module[Config]; add config: annotation. |
| dimos/core/tests/test_docker_deployment.py | Update test module to use config: annotation pattern. |
| dimos/core/test_native_module.py | Update native module test to use config: annotation pattern. |
| dimos/core/rpc_client.py | Simplify RPC client initialization defaults. |
| dimos/core/native_module.py | Remove generic Module[_Config]; switch to config: annotation. |
| dimos/core/module.py | Remove generic ModuleBase[...]; rely on annotation-based Configurable. |
| dimos/core/docker_module.py | Switch docker proxy config lookup to new config-type resolution approach. |
| dimos/core/coordination/module_coordinator.py | Remove ModuleBase[Any] typing in APIs. |
| dimos/core/coordination/blueprints.py | Remove ModuleBase[Any] typing in blueprint atoms/remappings. |
| dimos/control/coordinator.py | Remove Module[Config]; add config: annotation. |
| dimos/agents/vlm_agent.py | Remove Module[Config]; add config: annotation. |
| dimos/agents/skills/person_follow.py | Remove Module[Config]; add config: annotation. |
| dimos/agents/mcp/mcp_client.py | Remove Module[Config]; add config: annotation. |
| dimos/agents/agent_test_runner.py | Remove Module[Config]; add config: annotation. |
| dimos/agents_deprecated/modules/base_agent.py | Remove generic Module[Config]; add config: annotation. |
Comments suppressed due to low confidence (4)
dimos/perception/detection/reid/module.py:46
ReidModuledefines a module-specificConfigmodel, but the module class itself no longer declaresconfig: Config. With the new config resolution, this meansReidModulewill instantiate the baseModuleConfiginstead and theConfigclass becomes unused/misleading. Either addconfig: ConfigtoReidModule(and routeidsystemthrough config) or remove the unusedConfigmodel.
dimos/robot/unitree/go2/connection.py:213GO2Connectionnow declaresconfig: _Configwhere_Configis aTypeVar.Configurable.__init__will treat this as the config type and attemptconfig_type(**kwargs), which will fail because aTypeVarisn't instantiable. Since this class is instantiated directly (e.g.,dimos.deploy(GO2Connection, ip=ip)), theconfigannotation needs to be a concreteBaseConfigsubclass (likelyConnectionConfig), and any remaining generic-type plumbing should be removed or replaced with a runtime resolver.
dimos/robot/unitree/g1/sim.py:58G1ConnectionBaseis no longer generic, butG1SimConnectionstill inherits fromG1ConnectionBase[G1SimConfig]. This will raise at import time sinceG1ConnectionBasecan't be subscripted. Update the base class toG1ConnectionBaseand addconfig: G1SimConfigon this subclass so config instantiation uses the simulation config.
dimos/core/native_module.py:124- The
NativeModuledocstring still says subclasses should setdefault_config, but this PR removesdefault_configin favor ofconfig: ...annotations. Update the docstring to reflect the new config resolution mechanism so users don’t follow an invalid pattern.
"""Module that wraps a native executable as a managed subprocess.
Subclass this, declare In/Out ports, and set ``default_config`` to a
:class:`NativeModuleConfig` subclass pointing at the executable.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…rics Replace Generic-based config resolution with simple type annotation lookup. Classes now declare `config: MyConfig` instead of `Parent[MyConfig]`. Configurable.__init__ uses get_type_hints to find the config type. - Remove default_config from all classes - Remove Generic[ConfigT] from Configurable, Service, Module hierarchy - Simplify RPCClient and PubSubRPCMixin to use defaults directly
- Fix Bridge to be Generic for TypeVar binding - Fix MappingProxyType default for rpc_timeouts - Fix remaining TypeVar config annotations (GO2Connection, QuestTeleopModule)
The config annotation refactor made the AST scanner detect more Module subclasses (plain `Module` vs `Module[Config]` subscript). These classes were always missing start/stop but weren't caught before.
| default_config: type[ModuleConfigT] = ModuleConfig # type: ignore[assignment] | ||
|
|
||
| class ModuleBase(Configurable, Resource): | ||
| config: ModuleConfig |
There was a problem hiding this comment.
There are several places which still use default_config:
dimos/core/native_module.py:30: default_config = MyConfig
dimos/core/native_module.py:122: Subclass this, declare In/Out ports, and set ``default_config`` to a
dimos/protocol/service/test_lcmservice.py:129: def test_init_with_default_config(self) -> None:
dimos/simulation/unity/test_unity_sim.py:135: def test_default_config(self):
examples/docker_hello_world/hello_docker.py:65: default_config = HelloDockerConfig
examples/simplerobot/simplerobot.py:64: default_config = SimpleRobotConfig
docs/usage/native_modules.md:33: default_config = MyLidarConfig
docs/usage/native_modules.md:243: default_config = Mid360Config
docs/usage/transforms.md:182: default_config = MyModuleConfig
docs/usage/blueprints.md:19: default_config = ConnectionConfig
docs/usage/blueprints.md:47: default_config = Config
docs/usage/configuration.md:17: default_config = Config
docs/usage/configuration.md:59: default_config = Config
|
|
||
|
|
||
| class ReidModule(Module): | ||
| default_config = Config |
There was a problem hiding this comment.
Don't you need to add a config here too?
| default_config = LCMPubsubConfig | ||
| class LCMTF(PubSubTF): | ||
| config: LCMPubsubConfig | ||
| pass |
There was a problem hiding this comment.
| pass |
Summary
config: MyConfiginstead ofParent[MyConfig]Configurable.__init__usesget_type_hintsto find the config typedefault_configfrom all classes