Skip to content

feat(cli): add interactive RPC shell - #3236

Open
TomCC7 wants to merge 30 commits into
mainfrom
cc/feat/repl-module
Open

feat(cli): add interactive RPC shell#3236
TomCC7 wants to merge 30 commits into
mainfrom
cc/feat/repl-module

Conversation

@TomCC7

@TomCC7 TomCC7 commented Jul 28, 2026

Copy link
Copy Markdown
Member

Contribution path

  • No tracking issue; the lifecycle rationale and safety boundaries are documented below.

Problem

DimOS has no general interactive interface for discovering deployed modules and
calling their RPC methods. MCP only exposes skills and requires an McpServer,
which makes it a poor fit for low-level debugging.

Attaching during coordinator startup also had a race: discovery published one
ping and waited for that request. If the coordinator subscribed after the
publication, the shell could not recover when the coordinator became ready.

Solution

Shell and introspection APIs

  • Add a TTY-only dimos shell command backed by IPython.
  • Expose human-readable guide(), modules(), rpcs(), and describe()
    helpers, plus structured module/RPC metadata through app.
  • Preserve RPC signatures and docstrings for IPython inspection and support
    exact instance lookup when multiple modules share a class.
  • Connect directly to the coordinator; no run-registry entry or McpServer is
    required.

These are additive inspection APIs. RPC invocation still uses the existing path
and payload types.

Lifecycle changes

  • Coordinator service ownership: ModuleCoordinator.loop() now starts the
    coordinator RPC service instead of the two dimos run branches. loop() is
    the shared entrypoint for foreground, daemon, and direct
    blueprint.build().loop() launches, so all three become attachable. Daemon
    startup remains post-fork, shutdown remains in loop()'s finally block,
    and an RLock keeps explicit startup idempotent and serialized with stop.
  • Startup discovery: CoordinatorRPC.connect() retries ping every 250 ms
    within the existing five-second budget. A pub/sub ping sent before the
    coordinator subscribes is lost; retrying the request fixes that race without
    adding an unbounded wait.
  • Timeout cleanup: RPCSpec.call_sync() unsubscribes its local response
    callback on timeout. Retries otherwise leave unreachable callbacks in the
    shared response map. This does not invoke or cancel the remote RPC, and the
    successful-call path is unchanged.

This PR does not change MCP or skill exposure, RPC payload serialization, module
shutdown order, or RPC filtering/confirmation behavior.

How to Test

Start the test blueprint:

uv run dimos --viewer none --n-workers 1 run demo-mcp-stress-test

In another terminal:

uv run dimos shell

Manual test session:

Attached to run 20260727-221937-demo-mcp-stress-test (demo-mcp-stress-test).

In [1]: guide()
Quick start
  guide()                           Show this guide again
  modules()                         List deployed module instances
  rpcs()                            List every RPC
  rpcs("ModuleName")                Filter RPCs by module
  describe("ModuleName.method")     Show a signature and documentation
  app.ModuleName.method(...)        Invoke an RPC
  app.ModuleName.method?            Inspect an RPC with IPython

In [2]: modules()
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━┓
┃ Instance         ┃ Class            ┃ RPCs ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━┩
│ StressTestModule │ StressTestModule │ 10   │
│ McpServer        │ McpServer        │ 11   │
└──────────────────┴──────────────────┴──────┘

In [3]: rpcs("StressTestModule")
# Printed 10 RPCs with signatures and docstring summaries, including:
# StressTestModule.echo(message: str) -> str
# StressTestModule.ping() -> str

In [4]: describe("StressTestModule.echo")
RPC: StressTestModule.echo
Signature: echo(message: str) -> str

Documentation:
Echo back the given message. Used for latency and connectivity tests.

In [5]: app.StressTestModule.echo("manual shell test")
Out[5]: 'manual shell test'

In [6]: exit

The foreground blueprint then stopped cleanly with Ctrl-C.

Automated validation after merging current main:

169 passed: shell, cache CLI, porcelain, coordinator lifecycle/discovery,
            and RPC backend regressions
Mypy passed for all 922 source files
Ruff format and lint passed for all relevant Python files
uv lock --check passed

AI assistance

Codex with GPT-5 helped explore the existing coordinator and RPC abstractions,
draft the design, implement the change, write tests and documentation, and run
the automated and manual validation. The author reviewed the design decisions
through an interactive question-and-answer process.

Checklist

  • I have read and approved the CLA.

@mintlify

mintlify Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
dimensional 🟢 Ready View Preview Jul 28, 2026, 3:52 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlify Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
dimensional 🟡 Building Jul 28, 2026, 3:51 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Comment thread dimos/robot/cli/dimos.py Outdated
Comment thread dimos/core/coordination/module_coordinator.py
Comment thread dimos/core/coordination/module_coordinator.py Outdated
Comment thread dimos/porcelain/module_source.py
Comment thread dimos/porcelain/dimos.py Outdated
Comment thread dimos/porcelain/dimos.py Outdated
Comment thread dimos/porcelain/dimos.py Outdated
Comment thread dimos/protocol/rpc/spec.py
Comment thread dimos/robot/cli/dimos.py
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.60000% with 27 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
dimos/porcelain/dimos.py 79.26% 7 Missing and 10 partials ⚠️
dimos/porcelain/module_handle.py 78.26% 3 Missing and 2 partials ⚠️
dimos/robot/cli/shell.py 96.25% 2 Missing and 1 partial ⚠️
dimos/core/introspection/module/info.py 96.15% 0 Missing and 1 partial ⚠️
dimos/core/rpc_client.py 94.44% 0 Missing and 1 partial ⚠️
@@            Coverage Diff             @@
##             main    #3236      +/-   ##
==========================================
+ Coverage   74.90%   75.01%   +0.11%     
==========================================
  Files        1114     1118       +4     
  Lines      106086   106527     +441     
  Branches     9665     9690      +25     
==========================================
+ Hits        79461    79910     +449     
+ Misses      23816    23796      -20     
- Partials     2809     2821      +12     
Flag Coverage Δ
OS-ubuntu-24.04-arm 68.65% <94.60%> (+0.15%) ⬆️
OS-ubuntu-latest 70.65% <94.60%> (+0.13%) ⬆️
Py-3.10 70.65% <94.60%> (+0.14%) ⬆️
Py-3.11 70.64% <94.60%> (+0.13%) ⬆️
Py-3.12 70.64% <94.60%> (+0.13%) ⬆️
Py-3.13 70.65% <94.60%> (+0.13%) ⬆️
Py-3.14 70.65% <94.60%> (+0.13%) ⬆️
Py-3.14t 70.64% <94.60%> (+0.12%) ⬆️
SelfHosted-Large 29.31% <28.80%> (-0.02%) ⬇️
SelfHosted-Linux 35.88% <27.20%> (-0.05%) ⬇️
SelfHosted-macOS 34.98% <27.20%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
dimos/core/coordination/coordinator_rpc.py 95.16% <100.00%> (+7.16%) ⬆️
dimos/core/coordination/module_coordinator.py 85.00% <100.00%> (+0.57%) ⬆️
dimos/core/coordination/test_coordinator_rpc.py 100.00% <100.00%> (ø)
dimos/core/coordination/test_module_coordinator.py 99.56% <100.00%> (+0.01%) ⬆️
dimos/porcelain/local_module_source.py 100.00% <100.00%> (ø)
dimos/porcelain/module_source.py 100.00% <100.00%> (ø)
dimos/porcelain/remote_module_source.py 93.47% <100.00%> (+8.18%) ⬆️
dimos/porcelain/test_dimos.py 100.00% <100.00%> (ø)
dimos/porcelain/test_remote_module_source.py 98.37% <100.00%> (+0.57%) ⬆️
dimos/protocol/rpc/spec.py 96.22% <100.00%> (+0.07%) ⬆️
... and 8 more
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TomCC7
TomCC7 marked this pull request as ready for review July 28, 2026 06:45
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant