Skip to content

Conversation

@jeff-hykin
Copy link
Member

@jeff-hykin jeff-hykin commented Jan 28, 2026

Unlike jeff/blueprint/6 the undo-rename wasn't tested (yet)

@greptile-apps
Copy link

greptile-apps bot commented Jan 28, 2026

Greptile Overview

Greptile Summary

Implements a new RPC system with module references and Spec-based dependency injection. This PR introduces:

  • Module References: Modules can now declare dependencies on other modules via class annotations (either concrete module types or Spec protocols)
  • Spec-based Autowiring: Automatic dependency resolution matches modules to specs using structural and annotation compliance checking
  • Improved Type Safety: Added ModuleProxy type alias and extensive type hints throughout the codebase
  • API Refactoring: Renamed create_module_blueprint() to ModuleBlueprintSet.create() and ModuleConnection to StreamRef

Key changes:

  • ModuleBlueprint.create() now extracts both stream connections and module references from annotations
  • _connect_module_refs() performs sophisticated matching between module specs and available modules
  • New dimos/spec/utils.py module provides spec compliance checking with annotation-protocol library
  • Comprehensive test coverage including ambiguity handling and remapping scenarios
  • Documentation and examples updated to reflect the new API

Confidence Score: 3/5

  • This PR has a critical type safety bug that will cause runtime errors in certain scenarios
  • The implementation is well-structured with comprehensive tests, but the bug in _connect_module_refs at line 300 will cause a TypeError when remapping_map contains string values. The extensive test suite likely doesn't trigger this edge case with string remappings.
  • dimos/core/blueprints.py requires immediate attention to fix the type check bug

Important Files Changed

Filename Overview
dimos/core/blueprints.py Major refactor introducing module references and Spec-based autowiring; contains a type safety issue in _connect_module_refs
dimos/core/rpc_client.py Added ModuleProxy type alias for better type hints, minimal changes
dimos/core/module.py Added set_module_ref RPC method and updated blueprint reference
dimos/spec/utils.py New utility module for Spec protocol compliance checking

Sequence Diagram

sequenceDiagram
    participant User
    participant autoconnect
    participant ModuleBlueprintSet
    participant ModuleCoordinator
    participant Calculator as Calculator Module
    participant Client as Client Module
    participant RPCClient as ModuleProxy

    User->>autoconnect: autoconnect(Calculator.blueprint(), Client.blueprint())
    autoconnect->>ModuleBlueprintSet: Create blueprints with module_refs
    Note over ModuleBlueprintSet: Extract StreamRefs (In/Out)<br/>Extract ModuleRefs (Spec/Module annotations)
    
    User->>ModuleBlueprintSet: .build()
    ModuleBlueprintSet->>ModuleCoordinator: start()
    ModuleBlueprintSet->>ModuleCoordinator: _deploy_all_modules()
    ModuleCoordinator->>Calculator: Deploy module
    ModuleCoordinator->>RPCClient: Wrap in RPCClient (ModuleProxy)
    ModuleCoordinator->>Client: Deploy module
    ModuleCoordinator->>RPCClient: Wrap in RPCClient (ModuleProxy)
    
    ModuleBlueprintSet->>ModuleBlueprintSet: _connect_transports()
    Note over ModuleBlueprintSet: Connect In/Out streams via LCMTransport
    
    ModuleBlueprintSet->>ModuleBlueprintSet: _connect_rpc_methods()
    Note over ModuleBlueprintSet: Register RPC methods for discovery
    
    ModuleBlueprintSet->>ModuleBlueprintSet: _connect_module_refs()
    Note over ModuleBlueprintSet: Match Client.calc (ComputeSpec)<br/>to Calculator module
    ModuleBlueprintSet->>Client: set_module_ref("calc", calculator_proxy)
    Note over Client: Client.calc now references Calculator
    
    ModuleBlueprintSet->>ModuleCoordinator: start_all_modules()
    
    Client->>Calculator: self.calc.compute1(2, 3) via RPC
    Calculator-->>Client: Return 5
    Client->>Calculator: self.calc.compute2(1.5, 2.5) via RPC
    Calculator-->>Client: Return 4.0
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

mod_and_mod_ref_to_proxy = {
(module, name): replacement
for (module, name), replacement in self.remapping_map.items()
if is_spec(replacement) or issubclass(replacement, Module)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling issubclass(replacement, Module) will raise TypeError when replacement is a string (which is allowed by the type hint str | type[Module] on line 114)

Suggested change
if is_spec(replacement) or issubclass(replacement, Module)
if is_spec(replacement) or (isinstance(replacement, type) and issubclass(replacement, Module))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants