Skip to content

Commit 9c8caef

Browse files
committed
refactor(config): resolve config type from annotation instead of generics
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
1 parent 450cc27 commit 9c8caef

78 files changed

Lines changed: 219 additions & 245 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dimos/agents/agent_test_runner.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ class Config(ModuleConfig):
3131
messages: Iterable[BaseMessage]
3232

3333

34-
class AgentTestRunner(Module[Config]):
34+
class AgentTestRunner(Module):
35+
config: Config
3536
agent_spec: AgentSpec
3637
agent: In[BaseMessage]
3738
agent_idle: In[bool]

dimos/agents/mcp/mcp_client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ class McpClientConfig(ModuleConfig):
4646
mcp_server_url: str = "http://localhost:9990/mcp"
4747

4848

49-
class McpClient(Module[McpClientConfig]):
49+
class McpClient(Module):
50+
config: McpClientConfig
5051
agent: Out[BaseMessage]
5152
human_input: In[str]
5253
agent_idle: Out[bool]

dimos/agents/skills/person_follow.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Config(ModuleConfig):
5050
use_3d_navigation: bool = False
5151

5252

53-
class PersonFollowSkillContainer(Module[Config]):
53+
class PersonFollowSkillContainer(Module):
5454
"""Skill container for following a person.
5555
5656
This skill uses:
@@ -60,6 +60,8 @@ class PersonFollowSkillContainer(Module[Config]):
6060
- Does not do obstacle avoidance; assumes a clear path.
6161
"""
6262

63+
config: Config
64+
6365
color_image: In[Image]
6466
global_map: In[PointCloud2]
6567
cmd_vel: Out[Twist]

dimos/agents/vlm_agent.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ class VLMAgentConfig(ModuleConfig):
3535
system_prompt: str | None = SYSTEM_PROMPT
3636

3737

38-
class VLMAgent(Module[VLMAgentConfig]):
38+
class VLMAgent(Module):
3939
"""Stream-first agent for vision queries with optional RPC access."""
4040

41+
config: VLMAgentConfig
42+
4143
color_image: In[Image]
4244
query_stream: In[HumanMessage]
4345
answer_stream: Out[AIMessage]

dimos/agents_deprecated/modules/base_agent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ class BaseAgentConfig(ModuleConfig):
4646
rag_threshold: float = 0.45
4747
process_all_inputs: bool = False
4848

49-
class BaseAgentModule(BaseAgent, Module[BaseAgentConfig]): # type: ignore[misc]
49+
class BaseAgentModule(BaseAgent, Module): # type: ignore[misc]
5050
"""Agent module that inherits from BaseAgent and adds DimOS module interface.
5151
5252
This provides a thin wrapper around BaseAgent functionality, exposing it
5353
through the DimOS module system with RPC methods and stream I/O.
5454
"""
55+
config: BaseAgentConfig
5556

5657
# Module I/O - AgentMessage based communication
5758
message_in: In[AgentMessage] # Primary input for AgentMessage

dimos/control/coordinator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ class ControlCoordinatorConfig(ModuleConfig):
114114
tasks: list[TaskConfig] = field(default_factory=lambda: [])
115115

116116

117-
class ControlCoordinator(Module[ControlCoordinatorConfig]):
117+
class ControlCoordinator(Module):
118118
"""Centralized control coordinator with per-joint arbitration.
119119
120120
Single tick loop that:
@@ -142,6 +142,8 @@ class ControlCoordinator(Module[ControlCoordinatorConfig]):
142142
>>> orch.start()
143143
"""
144144

145+
config: ControlCoordinatorConfig
146+
145147
# Output: Aggregated joint state for external consumers
146148
joint_state: Out[JointState]
147149

dimos/core/coordination/blueprints.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ class ModuleRef:
7979
@dataclass(frozen=True)
8080
class _BlueprintAtom:
8181
kwargs: dict[str, Any]
82-
module: type[ModuleBase[Any]]
82+
module: type[ModuleBase]
8383
streams: tuple[StreamRef, ...]
8484
module_refs: tuple[ModuleRef, ...]
8585

8686
@classmethod
87-
def create(cls, module: type[ModuleBase[Any]], kwargs: dict[str, Any]) -> Self:
87+
def create(cls, module: type[ModuleBase], kwargs: dict[str, Any]) -> Self:
8888
streams: list[StreamRef] = []
8989
module_refs: list[ModuleRef] = []
9090

@@ -171,9 +171,7 @@ def global_config(self, **kwargs: Any) -> "Blueprint":
171171

172172
def remappings(
173173
self,
174-
remappings: list[
175-
tuple[type[ModuleBase[Any]], str, str | type[ModuleBase[Any]] | type[Spec]]
176-
],
174+
remappings: list[tuple[type[ModuleBase], str, str | type[ModuleBase] | type[Spec]]],
177175
) -> "Blueprint":
178176
remappings_dict = dict(self.remapping_map)
179177
for module, old, new in remappings:

dimos/core/coordination/module_coordinator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def suppress_console(self) -> None:
9696

9797
def deploy(
9898
self,
99-
module_class: type[ModuleBase[Any]],
99+
module_class: type[ModuleBase],
100100
global_config: GlobalConfig = global_config,
101101
**kwargs: Any,
102102
) -> ModuleProxy:
@@ -291,7 +291,7 @@ def load_blueprint(
291291
if hasattr(module, "on_system_modules"):
292292
module.on_system_modules(all_modules)
293293

294-
def load_module(self, module_class: type[ModuleBase[Any]], **kwargs: Any) -> None:
294+
def load_module(self, module_class: type[ModuleBase], **kwargs: Any) -> None:
295295
self.load_blueprint(module_class.blueprint(**kwargs))
296296

297297
def loop(self) -> None:

dimos/core/docker_module.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import subprocess
2525
import threading
2626
import time
27-
from typing import TYPE_CHECKING, Any
27+
from typing import TYPE_CHECKING, Any, get_type_hints
2828

2929
from dimos.core.module import ModuleBase, ModuleConfig
3030
from dimos.core.rpc_client import ModuleProxyProtocol, RpcCall
@@ -126,7 +126,7 @@ class DockerModuleProxy(ModuleProxyProtocol):
126126
config: DockerModuleConfig
127127

128128
def __init__(self, module_class: type[ModuleBase], *args: Any, **kwargs: Any) -> None:
129-
config_class = module_class._resolve_config_type()
129+
config_class = get_type_hints(module_class).get("config", DockerModuleConfig)
130130
if not issubclass(config_class, DockerModuleConfig):
131131
raise TypeError(
132132
f"{module_class.__name__} config must be a DockerModuleConfig subclass, "

dimos/core/module.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,14 @@ class _BlueprintPartial(Protocol):
9797
def __call__(self, **kwargs: Any) -> "Blueprint": ...
9898

9999

100-
class ModuleBase(Configurable[ModuleConfigT], Resource):
100+
class ModuleBase(Configurable, Resource):
101+
config: ModuleConfig
101102
# Deployment target. Worker managers declare which deployment type they
102103
# handle; the coordinator routes modules accordingly.
103104
deployment: ClassVar[Deployment] = "python"
104105

105106
_rpc: RPCSpec | None = None
106-
_tf: TFSpec[Any] | None = None
107+
_tf: TFSpec | None = None
107108
_loop: asyncio.AbstractEventLoop | None = None
108109
_loop_thread: threading.Thread | None
109110
_disposables: CompositeDisposable
@@ -393,7 +394,7 @@ def get_skills(self) -> list[SkillInfo]:
393394
return skills
394395

395396

396-
class Module(ModuleBase[ModuleConfigT]):
397+
class Module(ModuleBase):
397398
def __init_subclass__(cls, **kwargs: Any) -> None:
398399
"""Set class-level None attributes for In/Out type annotations.
399400

0 commit comments

Comments
 (0)