Skip to content

Agent refactor#1211

Merged
paul-nechifor merged 5 commits intodevfrom
pauln-agent-refactor
Feb 13, 2026
Merged

Agent refactor#1211
paul-nechifor merged 5 commits intodevfrom
pauln-agent-refactor

Conversation

@paul-nechifor
Copy link
Contributor

@paul-nechifor paul-nechifor commented Feb 7, 2026

Problem

We need a simpler base for agents so we can build long running tasks.

Closes DIM-447 ( https://linear.app/dimensional/issue/DIM-447/refactor-agents )

Solution

  • Switched from init_chat_model with custom tool handling to create_agent (the recommended way for the latest version of langchain)
  • Skill registration is no longer required. The agent now discovers tools automatically by calling get_skills() on all launched modules at startup via the new on_system_modules callback from ModuleCoordinator
  • Removed AgentSpec class and llm_init.py. The Agent is now a plain Module with a threaded message loop instead of an async coroutine-based one
  • Module no longer inherits from SkillContainer. Skill discovery uses the skill attribute set by the @skill decorator
  • Removed HumanInput module. Human input now comes in via the human_input stream on the Agent directly
  • Moved agents/cli/web.py to agents/web_human_input.py
  • Added AgentTestRunner module that feeds messages into the agent and waits for idle, used by the new test fixtures
  • Rewrote agent tests
  • Camera video_stream skill (which was a passive generator) replaced with take_a_picture that just returns the latest frame
  • Model/provider enums removed. Model is now just a string like "gpt-4o" or "ollama:qwen3:8b" or "huggingface:Qwen/Qwen2.5-1.5B-Instruct"
  • Blueprints updated: llm_agent(), human_input() replaced with just agent(). Added demo-agent and demo-agent-camera blueprints

Breaking Changes

Quite a few breaking changes.

  • @skill now does not support any arguments. All skills marked with it must return in a short time. They must return a string or an Image like before. If they want to return multiple things, they can return None and then use self.agent_spec.add_message(HumanMessage(...)) to add a new message at any time.
  • SkillModule is removed. Use Module instead.
  • SkillContainer, SkillCoordinator, and everything in dimos/protocol/skill/ is removed.
  • HumanInput module is removed.
  • llm_agent blueprint is removed, use agent instead.
  • AgentSpec (the old base class) is removed. The new AgentSpec is just a protocol with add_message (for use with the new RPC system).
  • Model is now a plain string, not an enum. Provider is encoded in the model string prefix.

How to Test

uv run dimos run unitree-go2-agentic
uv run humancli

...and prompt it anything like before.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 7, 2026

Greptile Overview

Greptile Summary

  • Replaces the prior dimos.agents implementation with a new dimos.agents3 Agent and skill3 discovery mechanism.
  • Removes the old skill protocol/coordinator plumbing (dimos.protocol.skill.*, dimos.core.skill_module) and updates blueprints/tests to match.
  • Updates CLI tooling/docs (removes skillspy, adds dotenv loading) and shifts system prompt import to agents3.
  • MCP integration is left in an inconsistent state: MCP bridge entrypoints remain, but MCPModule is effectively removed.

Confidence Score: 1/5

  • This PR is not safe to merge because MCP exports/blueprints are currently broken and the new skill/tool discovery path likely raises at runtime.
  • The changes delete the prior skill + MCP plumbing but leave dimos.protocol.mcp exporting MCPModule while the implementation is commented out, and unitree blueprints still reference it. Separately, get_skills3() builds schemas via langchain_core.tools.tool(attr).args_schema.model_json_schema(), which is not a stable contract and can raise during module discovery; the new Agent tool routing also appears to target RPC endpoints using Skill3Info.class_name rather than the actual RPC service name.
  • dimos/protocol/mcp/mcp.py, dimos/protocol/mcp/init.py, dimos/robot/unitree_webrtc/unitree_go2_blueprints.py, dimos/core/module.py, dimos/agents3/agent.py

Important Files Changed

Filename Overview
README.md Removes README mention of skillspy monitoring tool.
dimos/agents/init.py Removes all exports from dimos.agents package (now empty), which may break external imports expecting these symbols.
dimos/agents3/agent.py Introduces new threaded Agent implementation and dynamic tool creation from modules; contains RPC routing/schema concerns flagged in review comments.
dimos/core/module.py Removes SkillContainer base and adds get_skills3 discovery; schema generation approach likely breaks at runtime (flagged).
dimos/protocol/mcp/mcp.py Entire MCPModule implementation is commented out, but package still exports MCPModule; this breaks imports and MCP blueprints.
dimos/robot/cli/dimos.py Loads dotenv at startup and removes skillspy CLI subcommand.
dimos/robot/unitree_webrtc/unitree_go2_blueprints.py Switches to agents3 Agent blueprint and removes human_input; still references MCPModule blueprint which is currently broken.
pyproject.toml Removes skillspy console script entry.

Sequence Diagram

sequenceDiagram
    participant CLI as dimos CLI
    participant MC as ModuleCoordinator
    participant Agent as agents3.Agent
    participant Mod as Other Modules
    participant RPC as RPC (LCM)
    participant MCP as MCP Bridge (stdio<->tcp)

    CLI->>MC: deploy(Agent, modules...)
    CLI->>MC: start_all_modules()
    MC->>Mod: start()
    MC->>Agent: start()
    MC->>Agent: on_system_modules([RPCClient...])
    Agent->>RPC: get_skills3() (on each module)
    RPC-->>Agent: list[Skill3Info]
    Agent->>Agent: create_agent(tools from Skill3Info)

    Note over MCP: MCP expects a TCP server from MCPModule
    MCP->>RPC: connect(host:port)
    MCP-->>MCP: forwards JSON-RPC over TCP

    Agent->>Mod: tool call via RpcCall (remote_name/class_name)
    Mod-->>Agent: RPC response (or None if nowait)
    Agent-->>CLI: publish messages/idle state
Loading

Copy link
Contributor

@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.

8 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 374 to +377
result = tuple(self._bound_rpc_calls[m] for m in methods)
return result[0] if len(result) == 1 else result

@rpc
Copy link
Contributor

Choose a reason for hiding this comment

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

Tool schema generation bug

get_skills3() calls tool(attr).args_schema.model_json_schema() and then json.dumps(...). langchain_core.tools.tool() returns a Tool-like wrapper, and args_schema is not guaranteed to exist (or to be a Pydantic model with model_json_schema()), which will raise at runtime when enumerating skills. This needs to use a stable schema source (e.g., require __skill3__ functions to have an explicit Pydantic args_schema, or use StructuredTool.from_function(...).args_schema and then serialize that model/schema).

Comment on lines +137 to +140
def _get_tools_from_modules(
agent: Agent, modules: list[RPCClient], rpc: RPCSpec
) -> list[StructuredTool]:
skills = [skill for module in modules for skill in (module.get_skills3() or [])]
Copy link
Contributor

Choose a reason for hiding this comment

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

RpcCall target mismatch

_skill_to_tool() constructs RpcCall(..., name=skill.func_name, remote_name=skill.class_name, ...). remote_name is the module’s actor/service name used by RPCClient (typically module.actor_class.__name__), not an arbitrary class_name string returned by get_skills3(). If Skill3Info.class_name is the underlying Python class name (or differs from the deployed actor name), tool calls will be routed to a non-existent RPC endpoint. This should carry and use the actual RPC service name for the module instance that exposed the skill (or build the tool directly from the corresponding RPCClient instance rather than from a detached Skill3Info).

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 7, 2026

Additional Comments (2)

dimos/protocol/mcp/mcp.py
MCPModule is removed

dimos.protocol.mcp.__init__ still exports MCPModule, but dimos/protocol/mcp/mcp.py now has the entire MCPModule implementation commented out. Importing from dimos.protocol.mcp import MCPModule will fail at import time, and any blueprint that references MCPModule.blueprint() will crash. Restore a real MCPModule implementation (or remove/replace the export and all call sites).


dimos/robot/unitree_webrtc/unitree_go2_blueprints.py
Broken MCP blueprint reference

This blueprint still wires in MCPModule.blueprint() but dimos.protocol.mcp.mcp.MCPModule no longer exists (the file is commented out). As-is, running unitree_go2_agentic_mcp will crash during import/blueprint creation. Either reintroduce MCPModule or remove/replace this blueprint dependency consistently.

@paul-nechifor paul-nechifor changed the title Agent refactor WIP: Agent refactor Feb 7, 2026
@paul-nechifor paul-nechifor force-pushed the pauln-agent-refactor branch 3 times, most recently from 96f2d0a to ccbf5ad Compare February 11, 2026 00:07
@paul-nechifor paul-nechifor changed the title WIP: Agent refactor Agent refactor Feb 11, 2026
Copy link
Contributor

@leshy leshy left a comment

Choose a reason for hiding this comment

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

this nukes protocol skill/ enitrely and ideas behind this, but letting Paul own this, proper MCP will reintroduce all old features anyway
need to update others on skillspy, agentspy etc not being available anymore?

@paul-nechifor paul-nechifor merged commit ad956e7 into dev Feb 13, 2026
15 checks passed
spomichter added a commit that referenced this pull request Feb 21, 2026
Release v0.0.10: Manipulation Stack, MuJoCo Simulation, DDS Transport, Web and Native Visualization via Rerun


## Highlights

88+ commits, 20 contributors, 700+ files changed.

The TLDR: **a complete manipulation stack**, **MuJoCo simulation**, **DDS transport**, and **a rewritten visualization pipeline**. Agents are no longer bolted on top — they're refactored as native modules with direct stream access. The entire ROS message dependency has been removed from core DimOS, and we've added VR, phone, and arm teleoperation stacks. You can now vibecode a pick-and-place task from natural language to motor commands. Installation has been significantly streamlined — no more direnv, simpler setup, and the web viewer is now the default.

---

## 🚀 New Features

### Simulation
- **MuJoCo simulation module** — Run any DimOS blueprint in simulation with no hardware. Supports xArm and Unitree embodiments, parses MJCF/URDF for robot properties, monotonic clock timing (no `time.sleep`). `dimos --simulation run unitree-go2` ([#1035](#1035)) by @jca0
- **Simulation teleop blueprints** — Added simulation teleop blueprints for Piper, xArm6, and xArm7. ([#1308](#1308)) by @mustafab0

### Manipulation
- **Modular manipulation stack** — Full planning stack with Drake: FK/IK solvers (Jacobian + Drake optimization), RRT path planning, world model with obstacle monitoring, multi-robot management. xArm6/7 and Piper support. ([#1079](#1079)) by @mustafab0
- **Joint servo and cartesian controllers** — Joint position/velocity controllers and cartesian IK task with Pinocchio solver. PoseStamped stream input for real-time control. ([#1116](#1116)) by @mustafab0
- **GraspGen integration** — Grasp generation via Docker-hosted GPU model. Lazy container startup, thread-safe init, RPC `generate_grasps()` returns ranked PoseArray. ([#1119](#1119), [#1234](#1234)) by @JalajShuklaSS
- **Gripper control** — Gripper RPC methods on control coordinator, exposed adapter property for custom implementations. ([#1213](#1213)) by @mustafab0
- **Detection3D and Object support** — Object input topics, TF support on manipulation module, pointcloud-to-convex-hull for Drake imports. ([#1236](#1236)) by @mustafab0
- **Agentic pick and place** — Reimplemented manipulation skills for agent-driven pick-and-place workflows. ([#1237](#1237)) by @mustafab0

### Teleoperation
- **Quest VR teleoperation** — Full WebXR + Deno bridge stack. Quest controller data (pose, trigger, grip) streamed to DimOS modules. Monitor-style locking for control loops. ([#1215](#1215)) by @ruthwikdasyam
- **Phone teleoperation** — Control Go2 from your phone with a web-based teleop interface. ([#1280](#1280)) by @ruthwikdasyam
- **Arm teleop with Pinocchio IK** — Single and dual arm teleoperation using Pinocchio inverse kinematics. Blueprints for xArm, Piper, and dual configurations. ([#1246](#1246)) by @ruthwikdasyam

### Transports & Infrastructure
- **DDS transport protocol** — CycloneDDS transport with configurable QoS (high-throughput and reliable profiles). Optional install, benchmark integration. ([#1174](#1174)) by @Kaweees
- **Pubsub pattern subscriptions** — Glob and regex pattern matching for topic subscriptions. `subscribe_all()` for bridge-style consumers. Topic type encoding in channel strings (`/topic#module.ClassName`). ([#1114](#1114)) by @leshy
- **LCM raw bytes passthrough** — Skip `lcm_encode()` when message is already bytes. ([#1223](#1223)) by @leshy
- **Unified TimeSeriesStore** — Pluggable backends (InMemory, SQLite, Pickle, PostgreSQL) with SortedKeyList for O(log n) operations. Replaces the old replay system and TimestampedCollection. Collection API with slice, range, and streaming methods. ([#1080](#1080)) by @leshy
- **DimosROS benchmark tests** — Benchmark suite for ROS transport performance. ([#1087](#1087)) by @leshy

### Navigation
- **FASTLIO2 support** — Hardware-verified localization with arm64 support. Docker deployment with FAR Planner, terrain analysis, and bagfile playback mode. Builds or-tools from source on arm64. ([#1149](#1149)) by @baishibona
- **Native Livox + FASTLIO2 module** — First-class DimOS native module for Livox Mid-360 lidar with FASTLIO2 localization. ([#1235](#1235)) by @leshy

### Visualization
- **RerunBridge module and CLI** — New bridge that subscribes to all LCM messages and logs those with `to_rerun()` to Rerun viewer. GlobalConfig singleton, web viewer support. Replaces the old rerun initialization system. ([#1154](#1154)) by @leshy
- **Webcam rerun visualization** — Camera module logs to Rerun with pinhole projection for 3D visualization. ([#1117](#1117)) by @ruthwikdasyam
- **Default viewer switched to rerun-web** — Browser-based viewer is now the default for broader compatibility. No native viewer install needed. ([#1324](#1324)) by @spomichter

### Agents
- **Agent refactor** — Restructured agent module with cleaner imports and global config integration. ([#1211](#1211)) by @paul-nechifor
- **Timestamp knowledge** — Agents now have timestamp awareness in prompts for temporal reasoning. ([#1093](#1093)) by @ClaireBookworm
- **Observe skill** — Go2 can now observe (capture and describe) its environment via agent skill. ([#1109](#1109)) by @paul-nechifor

### Platform & Hardware
- **G1 without ROS** — Unitree G1 blueprints decoupled from ROS dependency. Lazy imports for fast startup. ([#1221](#1221)) by @jeff-hykin
- **ARM (aarch64) support** — DimOS runs on ARM hardware. Platform-conditional dependencies, open3d source builds for arm64. ([#1229](#1229)) by @jeff-hykin
- **Universal joint/hardware schema** — `HardwareComponent` dataclass with `JointState`, `JointName` type aliases. Backend registry with auto-discovery for SDK adapters. ([#1040](#1040), [#1067](#1067)) by @mustafab0

---

## 🔧 Improvements

- **Optional Dask** — Start without Dask using `--no-dask` flag. Startup time reduced from ~60s to ~45s. ([#1111](#1111), [#1232](#1232)) by @paul-nechifor
- **RPC rework** — Renamed `ModuleBlueprint` → `_BlueprintAtom`, `ModuleBlueprintSet` → `Blueprint`, `ModuleConnection` → `Stream`. Added `ModuleRef`, improved type hints throughout. ([#1143](#1143)) by @jeff-hykin
- **Image class simplification** — Rewritten as pure NumPy dataclass. Removed CUDA backend, unused methods (solve_pnp, csrt_tracker), and image_impls/ directory. ([#1161](#1161)) by @leshy
- **Odometry message cleanup** — Simplified Odometry message type. ([#1256](#1256)) by @leshy
- **Remove all ROS message dependencies** — Purged ROS message types from core DimOS. Refactored rosnav to use ROSTransport. Removed dead ROS bridge code. ([#1230](#1230)) by @alexlin2
- **Removed bad function serialization** — Eliminated unnecessary serialization of Python functions. ([#1121](#1121)) by @paul-nechifor
- **Benchmark IEC units** — Switched bandwidth benchmarks from SI to IEC units for accuracy. ([#1147](#1147)) by @leshy
- **Pubsub typing improvements** — Thread-safety locks on `subscribe_new_topics` and `subscribe_all`. Proper type params across pubsub stack. ([#1153](#1153)) by @leshy
- **Autogenerated blueprint list** — Blueprints are now auto-discovered and listed. ([#1100](#1100)) by @paul-nechifor
- **Generic Buttons message** — Renamed `QuestButtons` to `Buttons` with generic field names for cross-platform teleop. ([#1261](#1261)) by @ruthwikdasyam
- **Dev container uses ros-dev image** — `./bin/dev` now runs the ROS-enabled dev image. ([#1170](#1170)) by @leshy
- **LSP support** — Added python-lsp-server and python-lsp-ruff to dev dependencies. ([#1169](#1169)) by @leshy
- **Lazy-load pyrealsense2** — RealSense camera module uses lazy imports to avoid errors in simulation environments without the SDK. ([#1309](#1309)) by @spomichter
- **Removed unused mmcv and mmengine** — Dead Detic dependencies removed, eliminating slow source builds from install. ([#1319](#1319)) by @spomichter
- **Simplified installation** — Removed direnv requirement, streamlined install instructions across all platforms. ([#1315](#1315)) by @spomichter
- **DDS extra excluded from --all-extras** — `cyclonedds` requires a source build, so `dds` is now excluded from `uv sync --all-extras` by default. ([#1318](#1318)) by @spomichter
- **Nix pre-commit skip** — Skip pre-commit install if hooks already exist. ([#1162](#1162)) by @leshy
- **Removed base-requirements** — Consolidated dependency management. ([#1098](#1098)) by @paul-nechifor
- **Removed old graspnet** — Cleaned up deprecated graspnet version. ([#1248](#1248)) by @paul-nechifor
- **Code cleanup** — Removed `tofix` markers ([#1216](#1216)), fixed ruff issues ([#1112](#1112)), removed old README_installation.md ([#1101](#1101)) by @paul-nechifor

---

## 🐛 Bug Fixes

- Fix LFS updating (move from .local to venv) ([#1090](#1090)) by @jeff-hykin
- Launch hotfixes: git clone HTTPS, get_data main branch ([#1091](#1091)) by @spomichter
- Fix camera demo not showing in Rerun ([#1148](#1148)) by @jeff-hykin
- Default to rerun native viewer ([#1099](#1099)) by @Nabla7
- Fix exploration blocking agent loop ([#1258](#1258)) by @paul-nechifor
- Fix person-follow blocking agent loop ([#1278](#1278)) by @paul-nechifor
- Skip metric3d tests on unsupported xformers GPUs (Blackwell compute capability >9.0) ([#1225](#1225)) by @leshy
- Fix manipulation tests ([#1218](#1218), [#1247](#1247)) by @jeff-hykin, @paul-nechifor
- Fix control coordinator e2e test ([#1212](#1212)) by @mustafab0
- Fix xarm7-sim broken e2e tests ([#1294](#1294)) by @paul-nechifor
- Pin langchain to restore supported providers ([#1241](#1241)) by @spomichter
- Fix missing library dependencies in Nix flake ([#1240](#1240)) by @Kaweees
- Fix discord invite link ([#1122](#1122)) by @spomichter
- macOS edgecase fix ([#1096](#1096)) by @jeff-hykin
- Fix second N in logo ([#1250](#1250)) by @jeff-hykin
- Fix Unitree Go2 minor issues ([#1307](#1307)) by @paul-nechifor
- Fix broken tests ([#1305](#1305)) by @ruthwikdasyam
- Fix `uv sync` for some macOS systems ([#1322](#1322)) by @jeff-hykin
- Fix mmcv install ([#1313](#1313)) by @paul-nechifor
- Fix mypy issues ([#1150](#1150), [#1167](#1167), [#1257](#1257)) by @leshy, @paul-nechifor, @jeff-hykin
- Fix Nix install uv pip extras ([#1321](#1321)) by @spomichter

---

## 📚 Documentation

- **Major docs overhaul** — New README with feature grid, hardware table, quickstart. Navigation, transports, data streams, and agent docs. ([#1295](#1295)) by @leshy
- **Day 1 docs** — Comprehensive getting started guide, development docs, contributing guide, architecture overview. Executable blueprint docs via md-babel-py. ([#1064](#1064)) by @jeff-hykin
- **Arm integration guide** — How-to for integrating new robotic arms with DimOS. ([#1238](#1238)) by @mustafab0
- **MCP documentation update** — Updated MCP install and usage instructions. ([#1251](#1251)) by @Kaweees
- **Docker docs** — First pass on Docker deployment documentation. ([#1151](#1151)) by @leshy
- **Transports documentation** — Encode/decode mixins, SHM examples, ROS/DDS transport docs. ([#1107](#1107)) by @leshy
- **Rerun API examples** — Updated examples for the new RerunBridge API. ([#1262](#1262)) by @jeff-hykin
- **PR template** added ([#1172](#1172)) by @christiefhyang
- **Simplified install instructions** — Removed direnv, streamlined across all platforms. ([#1315](#1315)) by @spomichter
- **Python example restored** — Added back the Python usage example. ([#1317](#1317)) by @jeff-hykin
- **Nix install updated** — Replaced uv with pip for Nix compatibility. ([#1326](#1326)) by @ruthwikdasyam
- **README improvements** ([#1311](#1311)) by @paul-nechifor
- **Simplified writing docs** — Consolidated writing_docs to a single markdown file. ([#1254](#1254)) by @jeff-hykin

---

## 🏗️ CI & Build

- **ci-complete gate** — Dynamic branch protection via single aggregated status check. MD-only PRs no longer blocked. ([#1279](#1279)) by @spomichter
- **Path-based test filtering** — Test jobs fully skip (no container spin-up) when no relevant code changed. ([#1284](#1284), [#1286](#1286)) by @spomichter
- **Navigation docker build workflow** — CI builds for the ROS navigation stack. ([#1259](#1259)) by @spomichter
- **CUDA test marker** — `@pytest.mark.cuda` for GPU-dependent tests. ([#1220](#1220)) by @jeff-hykin
- **e2e test marker** — Marked end-to-end tests for selective CI runs. ([#1110](#1110)) by @paul-nechifor
- **pytest stdin fix** — Added `-s` to default addopts for LCM autoconf compatibility. ([#1320](#1320)) by @spomichter

---

## ⚠️ Breaking Changes

- **RPC renames**: `ModuleBlueprint` → `_BlueprintAtom`, `ModuleBlueprintSet` → `Blueprint`, `ModuleConnection` → `Stream` ([#1143](#1143))
- **Image class rewrite**: `CudaImage` and `NumpyImage` removed. Image is now a pure NumPy dataclass. Methods like `solve_pnp`, `csrt_tracker`, `from_depth`, `to_depth_meters` removed. ([#1161](#1161))
- **ROS messages removed from core**: All `to_ros`/`from_ros` conversion methods removed. Use `ROSTransport` instead. ([#1230](#1230))
- **QuestButtons → Buttons**: Renamed with generic field names. ([#1261](#1261))
- **RerunBridge replaces old rerun init**: `dimos.dashboard.rerun_init` removed. Use `RerunBridgeModule` or the `rerun-bridge` CLI. ([#1154](#1154))
- **Unitree directory restructuring**: `unitree_go2` → `unitree/go2`, `unitree_g1` → `unitree/g1`. Blueprint names updated. ([#1221](#1221))
- **Default viewer is now rerun-web**: Use `--viewer-backend rerun` to restore native viewer. ([#1324](#1324))

---

## Quickstart

```bash
# Install
uv pip install dimos[base,unitree]

# Try it (no hardware needed)
# NOTE: First run downloads ~2.4 GB from LFS
dimos --replay run unitree-go2

# Simulate
uv pip install dimos[base,unitree,sim]
dimos --simulation run unitree-go2
```

---

## New Contributors 🎉

- @ruthwikdasyam — Quest VR teleoperation, phone teleop, arm teleop, webcam rerun viz
- @JalajShuklaSS — GraspGen integration
- @jca0 — MuJoCo simulation module
- @christiefhyang — PR template

---

**Full Changelog**: [v0.0.9...v0.0.10](v0.0.9...v0.0.10)
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