WIP: Add Python runtime environments#2704
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
❌ 2 Tests Failed:
View the full list of 2 ❄️ flaky test(s)
To view more test analytics, go to the Test Analytics Dashboard |
…ixes Auto-fixes for cc/feat/venv-worker
Greptile SummaryThis PR adds isolated Python runtime environments for module workers. The main changes are:
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (3): Last reviewed commit: "fix: launch runtime workers from prepare..." | Re-trigger Greptile |
| ) | ||
| ``` | ||
|
|
||
| The v1 rules are concrete: |
There was a problem hiding this comment.
| The v1 rules are concrete: |
| WorkerManagerPython schedules the normal Python worker pool | ||
| PythonWorker controls one Python worker process | ||
| WorkerManagerExternal assigns external modules to machine workers | ||
| ExternalWorker controls one worker process on one machine |
There was a problem hiding this comment.
this should be controlling all the worker process on the single machine. since all modules it manages owns it's process there's no need to duplicate the worker process
|
|
||
| ### 3.1 Module contract shape | ||
|
|
||
| `ExternalModule` is a declarative `Module` subclass. It adds an implementation reference but no build, process, watchdog, or transport behavior. |
There was a problem hiding this comment.
| `ExternalModule` is a declarative `Module` subclass. It adds an implementation reference but no build, process, watchdog, or transport behavior. | |
| `ExternalModule` is a declarative `Module` subclass. It adds an implementation reference but no build, process, watchdog, or transport behavior. It's similar to current `NativeModule` but more "contract only". |
| ``` | ||
|
|
||
| ```python | ||
| class HeavyDetectorImpl(HeavyDetector): |
There was a problem hiding this comment.
| class HeavyDetectorImpl(HeavyDetector): | |
| import heavy_dependency | |
| class HeavyDetectorImpl(HeavyDetector): |
|
|
||
|
|
||
| class MLSPlanner(ExternalModule): | ||
| implementation = FsPath("target/release/mls_planner") |
There was a problem hiding this comment.
can support both str and path here no issue, and no need to import Path as FsPath
| path: Out[Path] | ||
| ``` | ||
|
|
||
| The implementation type is sufficient: |
There was a problem hiding this comment.
should not determine with the type itself... we can just scan the module folder and see what's there. if it's python/ then it's python. can also use heuristics to distinguish path and python module, should be fairly simple
|
|
||
| ```text | ||
| str Python class import reference | ||
| pathlib.Path native executable |
| - `local` always exists as an implicit target. | ||
| - modules absent from `assignments` run on `local`. | ||
| - an in-environment Python module, the most common module kind, cannot be assigned to a non-local target. | ||
| - each target name identifies one execution machine in v1; aliases for the same machine are rejected. |
There was a problem hiding this comment.
| - each target name identifies one execution machine in v1; aliases for the same machine are rejected. | |
| - each target name identifies one execution machine in v1; aliases for the same machine are rejected. | |
| One open question here is should we just extend blueprint to do this deployment assignment, or keep it separate and create a new registration system? |
| @dataclass(frozen=True) | ||
| class DeploymentSpec: | ||
| blueprint: Blueprint | ||
| targets: Mapping[str, ExecutionTarget] |
There was a problem hiding this comment.
need api shape for execution target as well
| contract: type[ExternalModule] | ||
| implementation: str | FsPath | ||
| implementation_dir: Path | ||
| preset: ConventionPreset |
There was a problem hiding this comment.
what is this? should not just dump type with no explanation
| Planning fails before mutation when: | ||
|
|
||
| - an assignment references a target absent from `targets`, | ||
| - an assignment references a module absent from the Blueprint, | ||
| - an in-environment Python module is assigned remotely, | ||
| - an `ExternalModule` has no discoverable implementation folder, | ||
| - zero or multiple Convention Presets match, | ||
| - a required lockfile, project file, source manifest, or build declaration is missing. |
There was a problem hiding this comment.
| Planning fails before mutation when: | |
| - an assignment references a target absent from `targets`, | |
| - an assignment references a module absent from the Blueprint, | |
| - an in-environment Python module is assigned remotely, | |
| - an `ExternalModule` has no discoverable implementation folder, | |
| - zero or multiple Convention Presets match, | |
| - a required lockfile, project file, source manifest, or build declaration is missing. |
too verbose
Problem
Python modules currently run in the coordinator environment, which forces module-specific dependency stacks into
dimos runand makes modules with complex or conflicting dependencies difficult to deploy safely.Closes N/A
Solution
Adds Python runtime environments for isolated module workers:
examples/dimos-demo-worker-module/with a runnable script showing main venv → isolated worker venv execution.Runtime structure
flowchart TD BP[Blueprint] --> MC[ModuleCoordinator] BP --> RP[RuntimePlacement<br/>Contract -> runtime + implementation] BP --> RR[RuntimeEnvironmentRegistry<br/>runtime name -> Runtime Project] MC --> Recon[Runtime Reconciliation<br/>uv/pixi locked sync] Recon --> Venv[Prepared Runtime Project venv<br/>.venv/bin/python] MC --> WMP[WorkerManagerPython] subgraph Existing["Existing default Python module path"] WMP --> DefaultPool[Default Python Worker Pool] DefaultPool --> Fork[ForkserverWorkerLauncher] Fork --> PyWorkerA[python_worker._worker_entrypoint] PyWorkerA --> ContractA[Module class instantiated directly] end subgraph New["New runtime-placed Python module path"] WMP --> RuntimePool[Runtime Python Worker Pool<br/>one pool per runtime] RuntimePool --> Cmd[CommandWorkerLauncher] Cmd --> PreparedPython[prepared .venv/bin/python] PreparedPython --> Entrypoint[venv_worker_entrypoint] Entrypoint --> PyWorkerB[python_worker._worker_entrypoint] PyWorkerB --> ContractB[Module Contract identity] PyWorkerB --> Impl[Runtime Implementation subclass] Impl --> Deps[Runtime-only dependencies] end RP --> WMP RR --> WMP Venv --> Cmd ContractB -. "RPC / streams / refs use contract identity" .-> MCRuntime placements do not replace the existing Python worker path. They add a second dispatch path inside
WorkerManagerPython: unplaced modules continue through the default forkserver pool, while placed Module Contracts are routed to a runtime-specific Python Worker Pool launched from the Runtime Project's prepared venv.Broader direction
This PR is the first concrete backend for a broader runtime-placement model: DimOS keeps a stable Module Contract in the blueprint graph, while execution can move into a backend-specific runtime.
flowchart TD Goal[End goal: remotely deployable, mixed-language DimOS modules] Seam[Stable seam introduced here<br/>Module Contract + RuntimePlacement + Python Worker Pool] Today[This PR<br/>Local locked Python Runtime Project] Remote[Future<br/>Remote Python Runtime Project<br/>SSH/container/robot-side venv] Native[Future<br/>Native Module Runtime<br/>Rust/C++ process + native SDK] Goal --> Remote Goal --> Native Remote --> Seam Native --> Seam Seam --> Today Today --> Contract[Dependency-light Module Contract] Today --> Impl[Runtime Implementation subclass] Today --> Venv[Prepared .venv/bin/python] Today --> SameSurface[Same DimOS RPC / streams / lifecycle surface]The immediate feature is local Python dependency isolation. The longer-term value is the separation between what DimOS sees and where the module runs. That same seam is what remote Python workers and native module runtimes can reuse without changing blueprint-level module identity.
Key tradeoffs:
How to Test
Expected: prints the repo/main Python executable, a worker Python executable under
examples/dimos-demo-worker-module/.venv/, runtime-only dependency outputRuntimeDependency, andworker result: demo-runtime:HELLO FROM MAIN VENV.Contributor License Agreement