Conversation
* Reapply "Module config adjustments (#1413)" (#1417) This reverts commit 3df8857. * Fixes * Move global_config * Why did this not commit? * Default * Fix * Fix * Fix * Docs * tentative fix for timeout error * Fix * Use create_autospec * TemporalMemory fix * Forbid extra * Fix --------- Co-authored-by: Sam Bull <Sam.B@snowfalltravel.com> Co-authored-by: Paul Nechifor <paul@nechifor.net>
* fix(imports): remove dunder init * fix import
* fix(deps): skip pyrealsense2 on macOS (not available) * -
* memory plans
* spec iteration
* spec iteration
* query objects spec
* mem3 iteration
* live/passive transforms
* initial pass on memory
* transform materialize
* sqlite schema: decomposed pose columns, separate payload table, R*Tree spatial index, lazy data loading
- Pose stored as 7 real columns (x/y/z + quaternion) instead of blob, enabling R*Tree spatial indexing
- Payload moved to separate {name}_payload table with lazy loading via _data_loader closure
- R*Tree virtual table created per stream for .near() bounding-box queries
- Added __iter__ to Stream for lazy iteration via fetch_pages
- Added embedding_stream() to Session ABC
- Updated _streams metadata with parent_stream and embedding_dim columns
- Codec module extracted (LcmCodec, PickleCodec, codec_for_type)
- Fixed broken memory_old.timeseries imports (memory.timeseries → memory_old.timeseries)
- Tests now use real Image data from TimedSensorReplay("unitree_go2_bigoffice/video")
- 32/32 tests passing, mypy clean
* JpegCodec for Image storage (43x smaller), ingest helpers, QualityWindowTransformer, E2E test
- Add JpegCodec as default codec for Image types (2.76MB → 64KB per frame)
- Preserve frame_id in JPEG header; ts stored in meta table
- Add ingest() helper for bulk-loading (ts, payload) iterables into streams
- Add QualityWindowTransformer: best-frame-per-window (supports backfill + live)
- EmbeddingTransformer sets output_type=Embedding automatically
- Require payload_type when creating new streams (no silent PickleCodec fallback)
- TransformStream.store() accepts payload_type, propagated through materialize_transform
- E2E test: 5min video → sharpness filter → CLIP embed → text search
- Move test_sqlite.py next to sqlite.py, update Image comparisons for lossy codec
- Add sqlite-vec dependency
* Wire parent_id lineage through transforms for automatic source data projection
- Add parent_id to Observation, append(), do_append(), and _META_COLS
- All transformers (PerItem, QualityWindow, Embedding) pass obs.id as parent_id
- SqliteEmbeddingBackend._row_to_obs() wires _source_data_loader via parent_id
- EmbeddingObservation.data now auto-projects to parent stream's payload (e.g. Image)
- No more timestamp-matching hacks to find source data from embedding results
* Wire parent_stream into _streams registry, add tasks.md gap analysis
- materialize_transform() now UPDATEs _streams.parent_stream so stream-level
lineage is discoverable (prerequisite for .join())
- Fix mypy: narrow parent_table type in _source_loader closure
- Add plans/memory/tasks.md documenting all spec-vs-impl gaps
* Implement project_to() for cross-stream lineage projection
Adds LineageFilter that compiles to nested SQL subqueries walking the
parent_id chain. project_to(target) returns a chainable target Stream
using the same _with_filter mechanism as .after(), .near(), etc.
Also fixes _session propagation in search_embedding/search_text.
* Make search_embedding auto-project to source stream
EmbeddingStream is a semantic index — search results should be source
observations (Images), not Embedding objects. search_embedding now
auto-projects via project_to when lineage exists, falling back to
EmbeddingStream for standalone streams without parent lineage.
* CaptionTransformer + Florence2 batch fix
- Add CaptionTransformer: wraps Captioner/VlModel, uses caption_batch()
for backfill efficiency, auto-creates TextStream with FTS on .store()
- Fix Florence2 caption_batch() emitting <pad> tokens (skip_special_tokens)
- E2E script now uses transform pipeline for captioning search results
* ObservationSet: fetch() returns list-like + stream-like result set
fetch() now returns ObservationSet instead of plain list, keeping you
in the Stream API. This enables fork-and-zip (one DB query, two uses)
and in-memory re-filtering without re-querying the database.
- Add matches(obs) to all filter dataclasses for in-Python evaluation
- Add ListBackend (in-memory StreamBackend) and ObservationSet class
- Filtered .appended reactive subscription via matches() infrastructure
- Update e2e export script to use fork-and-zip pattern
- 20 new tests (64 total, all passing)
* search_embedding accepts str/image with auto-embedding
EmbeddingStream now holds an optional model reference, so
search_embedding auto-dispatches: str → embed_text(), image → embed(),
Embedding/list[float] → use directly. The model is wired through
materialize_transform and also accepted via embedding_stream().
* Add sqlite_vec to mypy ignore list (no type stubs available)
* Fix mypy + pytest errors across memory and memory_old modules
- Fix SpatialImage/SpatialEntry dataclass hierarchy in memory_old
- Fix import path in memory_old/test_embedding.py
- Add None guard for obs.ts in run_viz_demo.py
- Add payload_type/session kwargs to base Stream.store() signature
- Type-annotate embeddings as EmbeddingStream in run_e2e_export.py
- Add similarity scores, raw search mode, pose ingest, viz pipeline
* Improve similarity heatmap with normalized values and distance spread
- Normalize similarity scores relative to min/max (CLIP clusters in narrow band)
- Add distance_transform_edt spread so dots radiate outward, fading to 0
- Bump default search k to 200 for denser heatmaps
* Remove plans/ from tracking (kept locally)
* Address Greptile review: SQL injection guards, distance ordering, stubs
- Validate stream names and tag keys as SQL identifiers
- Allowlist order_by fields to {id, ts}
- Re-sort vector search results by distance rank after IN-clause fetch
- Make TagsFilter hashable (tuple of pairs instead of dict)
- Remove dead code in memory_old/embedding.py
- Add scipy-stubs, fix distance_transform_edt type annotations
* Add memory Rerun visualization, fix stream iteration, update docs
- Add dimos/memory/rerun.py: to_rerun() sends stream data to Rerun
with auto-derived entity paths and no wall-clock timeline contamination
- Fix Stream.fetch_pages() to respect limit_val (was always overridden
by batch_size, making .limit() ineffective during iteration)
- Update viz.py: normalize similarities with 20% floor cutoff,
sort timeline by timestamp, add log_top_images()
- Convert run_e2e_export.py to pytest with cached DB fixture
- Update plans/memory docs to match current implementation
* Rename run_e2e_export → test_e2e_export, delete viz.py + run_viz_demo, fix mypy
- Rename to test_e2e_export.py (it's a pytest file, not a standalone script)
- Fix Generator return type and type: ignore for mypy
- Delete viz.py (replaced by rerun.py) and run_viz_demo.py
- Update docs/api.md to reference rerun.py instead of viz.py
* added docs
* removed tasks.md
* Optimize memory pipeline: TurboJPEG codec, sharpness downsample, thread reduction
- Switch JpegCodec from cv2.imencode to TurboJPEG (2-5x faster encode/decode)
- Lower default JPEG quality from 90 to 50 for smaller storage footprint
- Downscale sharpness computation to 160px Laplacian variance (10-20x cheaper)
- Add MemoryModule with plain-Python sharpness windowing (no rx timer overhead)
- Limit OpenCV threads: 2 globally in worker entrypoint, 1 in MemoryModule
- Cap global rx ThreadPoolScheduler at 8 workers (was unbounded cpu_count)
- Refactor SqliteEmbeddingBackend/SqliteTextBackend to use _post_insert hook
- Encode payload before meta insert to prevent orphaned rows on codec error
- Add `dimos ps` CLI command and `dps` entrypoint for non-interactive process listing
- Add unitree-go2-memory blueprint
* text embedding transformer
* cleanup
* Use Codec protocol type instead of concrete union, remove dead _pose_codec
* correct db sessions
* record module cleanup
* memory elements are now Resource, simplification of memory Module
* Rename stream.appended to stream.observable()/subscribe()
Mirror the core In stream API — memory streams now expose
.observable() and .subscribe() instead of the .appended property.
* repr, embedding fetch simplification
* Make Observation generic: Observation[T] with full type safety
* Simplify Stream._clone with copy.copy, remove subclass overrides
* loader refactor
* Extract backend.load_data(), add stream.load_data(obs) public API
SQL now lives on the backend, closures are thin thread-guarded wrappers.
* Add rich colored __str__ to Stream and Filter types
print() now shows colored output (class=cyan, type=yellow, name=green,
filters=cyan, pipes=dim). __repr__ stays plain for logs.
* Unify __repr__ and __str__ via _rich_text().plain, remove duplicate rendering
* renamed types to type
* one -> first, time range
* getitem for streams
* readme sketch
* bigoffice db in lfs, sqlite accepts Path
* projection transformers
* stream info removed, stream accessor helper, TS unique per stream
* Add colored summary() output and model= param to search_embedding
summary() now renders the rich-text stream header with colored type info,
count, timestamps, and duration. search_embedding() accepts an optional
model= override so callers don't need to attach a model to the stream.
* stream delete
* florence model detail settings and prefix filter
* extracted formatting to a separate file
* extract rich text rendering to formatting.py, add Stream.name, fix stale tests
Move all _rich_text methods from type.py and stream.py into a central
formatting.py module with a single rich_text() dispatch function.
Replace relative imports with absolute imports across memory/.
Add Stream.name property, remove VLMDetectionTransformer tests, fix
stale test assertions.
* matching based on streams
* projection experiments
* projection bugfix
* observationset typing fix
* detections, cleanup
* mini adjustments
* transform chaining
* memory2: lazy pull-based stream system
Greenfield rewrite of the memory module using sync generators.
Every .filter(), .transform(), .map() returns a new Stream — no
computation until iteration. Backends handle query application;
transforms are Iterator[Obs] → Iterator[Obs]. Live mode with
backpressure buffers bridges push sources to pull consumers.
* memory2: fix typing — zero type:ignore, proper generics
- Closed → ClosedError (N818)
- Callable types for _loader, Disposable.fn, backend_factory, PredicateFilter.fn
- Disposable typed in stream._live_sub
- assert+narrowing instead of type:ignore in KeepLast.take, _iter_transform
- cast only in Session.stream (unavoidable generic cache lookup)
* memory2: fix .live() on transform streams — reject with clear error
Live items from the backend buffer were bypassing the transform chain
entirely. The fix: .live() is only valid on backend-backed streams;
transforms downstream just see an infinite iterator.
* memory2: replace custom Disposable with rxpy DisposableBase
Use reactivex.abc.DisposableBase in protocols and reactivex.disposable.Disposable
in implementations, consistent with dimos's existing Resource pattern.
* memory2: extract filters and StreamQuery from type.py into filter.py
type.py now only contains Observation and its helpers.
* memory2: store transform on Stream node, not as source tuple
Stream._source is now `Backend | Stream` instead of `Backend | tuple[Stream, Transformer]`.
The transformer lives on the stream that owns it (`_xf` field), not bundled into the
source pointer. Fix .map() tests to pass Observation→Observation lambdas. Remove live
mode tests (blocked by nvidia driver D-state in root conftest autoconf).
* memory2: move live logic from Stream into Backend via StreamQuery
Live is now just a query parameter (live_buffer on StreamQuery). Stream.live()
is a one-liner query modifier — the backend handles subscription, dedup, and
backpressure internally. Stream has zero live implementation.
* memory2: extract impl/ layer with MemoryStore and SqliteStore scaffold
Move ListBackend from backend.py into impl/memory.py alongside new
MemorySession and MemoryStore. Add SqliteStore/SqliteSession/SqliteBackend
skeleton in impl/sqlite.py. Refactor Store and Session to abstract base
classes with _create_backend() hook. backend.py now only contains the
Backend and LiveBackend protocols.
Also fix doclinks: disambiguate memory.py reference in transports docs,
and include source .md file path in all doclinks error messages.
* memory2: add buffer.py docstring and extract buffer tests to test_buffer.py
* memory2: add Codec protocol and grid test for store implementations
Introduce codecs/ package with the Codec[T] protocol (encode/decode).
Thread payload_type through Session._create_backend() so backends can
select the right codec. Add test_impl.py grid test that runs the same
15 basic tests against every store backend (memory passes, sqlite xfail
until implemented).
* memory2: add codec implementations (pickle, lcm, jpeg) with grid tests
PickleCodec for arbitrary objects, LcmCodec for DimosMsg types,
JpegCodec for Image types with TurboJPEG. codec_for() auto-selects
based on payload type. Grid test verifies roundtrip preservation
across all three codecs using real PoseStamped and camera frame data.
* resource: add context manager to Resource; make Store/Session Resources
Resource.__enter__/__exit__ calls start()/stop(), giving every Resource
context-manager support. memory2 Store and Session now extend Resource
instead of bare ABC, replacing close() with the standard start()/stop()
lifecycle.
* resource: add CompositeResource with owned disposables
CompositeResource extends Resource with a _disposables list and own()
method. stop() disposes all children — gives tree-structured resources
automatic cleanup. Session and Store now extend CompositeResource.
* memory2: add BlobStore ABC with File and SQLite implementations
BlobStore separates payload blob storage from metadata indexing.
FileBlobStore stores on disk ({root}/{stream}/{key}.bin),
SqliteBlobStore uses per-stream tables. Grid tests cover both.
* memory2: move blobstore.md into blobstore/ as module readme
* memory2: add embedding layer, vector/text search, live safety guards
- EmbeddedObservation with derive() promotion semantics
- EmbedImages/EmbedText transformers using EmbeddingModel ABC
- .search(vec, k) and .search_text() on Stream with Embedding type
- VectorStore ABC for pluggable vector backends
- Backend.append() takes Observation directly (not kwargs)
- is_live() walks source chain; search/order_by/fetch/count guard
against live streams with TypeError instead of silent hang
- .drain() terminal for constant-memory side-effect pipelines
- Rewrite test_stream.py to use Stream layer (no manual backends)
* memory2: add documentation for streaming model, codecs, and backends
- README.md: architecture overview, module index, quick start
- streaming.md: lazy vs materializing vs terminal evaluation model
- codecs/README.md: codec protocol, built-in codecs, writing new ones
- impl/README.md: backend guide with query contract and grid test setup
* query application refactor
* memory2: replace LiveBackend with pluggable LiveChannel, add Configurable pattern
- Replace LiveBackend protocol with LiveChannel ABC (SubjectChannel for
in-memory fan-out, extensible to Redis/Postgres for cross-process)
- Add livechannel/ subpackage with SubjectChannel implementation
- Make Store and Session extend Configurable[ConfigT] with StoreConfig
and SessionConfig dataclasses
- Remove redundant Session._backends dict (Backend lives in Stream._source)
- Make list_streams() and delete_stream() abstract on Session so
implementations can query persisted streams
- StreamNamespace delegates to list_streams()/stream() instead of
accessing _streams directly
- Remove LiveBackend isinstance guard from stream.py — all backends
now have a built-in LiveChannel
* memory2: make backends Configurable, add session→stream config propagation
Session.stream() now merges session-level defaults with per-stream
overrides and forwards them to _create_backend(). Backends (ListBackend,
SqliteBackend) extend Configurable[BackendConfig] so they receive
live_channel, blob_store, and vector_store through the standard config
pattern instead of explicit constructor params.
* memory2: wire VectorStore into ListBackend, add MemoryVectorStore
ListBackend.append() now delegates embedding storage to the pluggable
VectorStore when configured. _iterate_snapshot() uses VectorStore.search()
for ANN ranking when available, falling back to brute-force in
StreamQuery.apply(). Adds MemoryVectorStore (in-memory brute-force impl)
and tests verifying end-to-end config propagation including per-stream
vector_store overrides.
* memory2: wire BlobStore into ListBackend with lazy/eager blob loading
Payloads are encoded via auto-selected codec and externalized to the
pluggable BlobStore on append. Observations become lightweight metadata
with lazy loaders that fetch+decode on first .data access. Per-stream
eager_blobs toggle pre-loads data during iteration.
* memory2: allow bare generator functions as stream transforms
stream.transform() now accepts Iterator→Iterator callables in
addition to Transformer subclasses, for quick stateful pipelines.
* memory2: update docs to reflect current API
- impl/README: LiveBackend → LiveChannel, add Configurable pattern,
update _create_backend and Store/Session signatures
- embeddings.md: fix Observation fields (_source → _loader),
embedding type (np.ndarray → Embedding), remove unimplemented
source chain, use temporal join for lineage
- streaming.md: note .transform() accepts bare callables
- README: add FnIterTransformer, generator function example
* memory2: implement full SqliteBackend with vec0 vector search, JSONB tags, and SQL filter pushdown
- Add SqliteVectorStore using sqlite-vec vec0 virtual tables with cosine distance
- Implement SqliteBackend: append, iterate (snapshot/live/vector), count with SQL pushdown
- Add SQL filter compilation for time, tags, and range filters; Python fallback for NearFilter/PredicateFilter
- Wire SqliteSession with _streams registry table, codec persistence, shared store auto-wiring
- Support eager blob loading via co-located JOIN optimization
- Load sqlite-vec extension in SqliteStore with graceful fallback
- Remove xfail markers from test_impl.py — all 36 grid tests pass
* memory2: stream rows via cursor pagination instead of fetchall()
Add configurable page_size (default 256) to BackendConfig. SqliteBackend
now iterates the cursor with arraysize set to page_size for memory-efficient
streaming of large result sets.
* memory2: add lazy/eager blob tests and spy store delegation grid tests
- TestBlobLoading: verify lazy (_UNLOADED sentinel + loader) vs eager (JOIN inline)
paths for SqliteBackend, plus value equivalence between both modes
- TestStoreDelegation: grid tests with SpyBlobStore/SpyVectorStore injected into
both memory and sqlite backends — verify append→put, iterate→get, and search
delegation through the pluggable store ABCs
* memory2: add R*Tree spatial index for NearFilter SQL pushdown, add e2e tests
R*Tree virtual tables enable O(log n) pose-based proximity queries instead
of full-table Python scans. E2E tests verify import pipeline and read-only
queries against real robot sensor data (video + lidar).
* auto index tags
* memory/stream str, and observables
* live stream is a resource
* readme work
* streams and intro
* renamed readme to arch
* Rename memory2 → memory, fix all imports and type errors
- Replace all dimos.memory2 imports with dimos.memory
- Make concrete filter classes inherit from Filter ABC
- Fix mypy errors: type narrowing, Optional guards, annotation mismatches
- Fix test_impl.py: filter_tags() → tags()
- Remove intro.py (superseded by intro.md)
- Delete old dimos/memory2/ directory
* Revert memory rename: restore memory/ from dev, new code lives in memory2/
- Restore dimos/memory/ (old timeseries memory) to match dev
- Move new memory system back to dimos/memory2/ with corrected imports
- Delete dimos/memory_old/ (no longer needed)
- Fix memory_old imports in tf.py, timestamped.py, replay.py → dimos.memory
- Remove dps CLI util and pyproject entry
- Remove unitree_go2_memory blueprint (depends on deleted modules)
* Remove stray old memory module references
- Delete empty dimos/memory/impl/sqlite.py
- Remove nonexistent memory-module entry from all_blueprints
- Restore codeblocks.md from dev
* Remove LFS test databases from PR
These were added during development but shouldn't be in the PR.
* Address review findings: SQL injection guards, type fixes, cleanup
- Remove dead dict(hits) and thread-affinity assertion in SqliteBackend
- Validate order_field and tag keys against _IDENT_RE to prevent SQL injection
- Replace assert bs is not None with RuntimeError for -O safety
- Add hash=False to NearFilter.pose, TagsFilter.tags, PredicateFilter.fn
- Collapse CaptionDetail enum to 3 distinct levels (BRIEF/NORMAL/DETAILED)
- Fix Stream.map() return type: Stream[Any] → Stream[R]
- Update architecture.md: SqliteBackend status Stub → Complete
- Document SqliteBlobStore commit responsibility
- Guard ImageDetections.ts against image=None
* Revert detection type changes: keep image as required field
Restores detection2d/bbox.py, imageDetections.py, and utils.py to
dev state — the image-optional decoupling is not needed for memory2.
* add libturbojpeg to docker image
* Make turbojpeg import lazy so tests skip gracefully in CI
Move top-level turbojpeg import in Image.py to the two methods that
use it, and guard jpeg codec tests behind ImportError / importorskip
so the test suite passes when libturbojpeg is not installed.
* Give each SqliteBackend its own connection for WAL-mode concurrency
Previously all backends shared a single sqlite3.Connection — concurrent
writes from different streams could interleave commits/rollbacks. Now
SqliteSession opens a dedicated connection per backend, with per-backend
blob/vector stores wrapping the same connection for atomicity. A separate
registry connection handles the _streams table.
Also makes SqliteBackend a CompositeResource so session.own(backend)
properly closes connections on stop, and fixes live iterator cleanup in
both backends (backfill phase now inside try/finally).
* Block search_text on SqliteBackend to prevent full table scans
search_text previously loaded every blob from the DB and did Python
substring matching — a silent full table scan. Raise NotImplementedError
instead until proper SQL pushdown is implemented.
* Catch RuntimeError from missing turbojpeg native library in codec tests
TurboJPEG import succeeds but instantiation raises RuntimeError when
the native library isn't installed. Skip the test case gracefully.
* pr comments
* occupancy change undo
* tests cleanup
* compression codec added, new bigoffice db uploaded
* correct jpeg codec
* PR comments cleanup
* blobstore stream -> stream_name
* vectorstore stream -> stream_name
* resource typing fixes
* move type definitions into dimos/memory2/type/ subpackage
Separate pure-definition files (protocols, ABCs, dataclasses) from
implementation files by moving them into a type/ subpackage:
- backend.py → type/backend.py
- type.py → type/observation.py
- filter.py → type/filter.py
Added type/__init__.py with re-exports for convenience imports.
Updated all 24 importing files across the module.
* lz4 codec included, utils/ cleanup
* migrated stores to a new config system
* config fix
* rewrite
* update memory2 docs to reflect new architecture
- Remove Session layer references (Store → Stream directly)
- Backend → Index protocol, concrete Backend composite
- SessionConfig/BackendConfig → StoreConfig
- ListBackend/SqliteBackend → ListIndex/SqliteIndex
- Updated impl README with new 'writing a new index' guide
- Verified intro.md code blocks via md-babel-py
* rename LiveChannel → Notifier, SubjectChannel → SubjectNotifier
Clearer name for the push-notification ABC — "Notifier" directly
conveys its subscribe/notify role without leaking the "live" stream
concept into a lower layer.
* rename Index → MetadataStore, drop Backend property boilerplate, simplify Store.stream()
- Index → MetadataStore, ListIndex → ListMetadataStore, SqliteIndex → SqliteMetadataStore
Consistent naming with BlobStore/VectorStore. Backend composition reads:
MetadataStore + BlobStore + VectorStore + Notifier
- Backend: replace _private + @Property accessors with plain public attributes
- Store.stream(): use model_dump(exclude_none=True) instead of manual dict filtering
* rename MetadataStore → ObservationStore
Better name — describes what it stores, not the kind of data.
Parallels BlobStore/VectorStore naturally.
* self-contained SQLite components with dual-mode constructors (conn/path)
Move table DDL into SqliteObservationStore.__init__ so all three SQLite
components (ObservationStore, BlobStore, VectorStore) are self-contained
and can be used standalone with path= without needing a full Store.
- Extract open_sqlite_connection utility from SqliteStore._open_connection
- Add path= keyword to SqliteBlobStore, SqliteVectorStore, SqliteObservationStore
- Promote BlobStore/VectorStore base classes to CompositeResource for
clean connection ownership via register_disposables
- SqliteStore now closes backend_conn directly instead of via metadata_store.stop()
- Add standalone component tests verifying path= mode works without Store
* move ObservationStore classes into observationstore/ directory
Matches the existing pattern of blobstore/ and vectorstore/ having their
own directories. SqliteObservationStore + helpers moved from impl/sqlite.py,
ListObservationStore moved from impl/memory.py. impl/ files now import
from the new location.
* add RegistryStore to persist fully-resolved backend config per stream
The old _streams table only stored (name, payload_module, codec_id), so
stream overrides (blob_store, vector_store, eager_blobs, page_size, etc.)
were lost on reopen. RegistryStore stores the complete serialized config
as JSON, enabling _create_backend to reconstruct any stream identically.
Each component (SqliteBlobStore, FileBlobStore, SqliteVectorStore,
SqliteObservationStore, SubjectNotifier) gets a pydantic Config class and
serialize/deserialize methods. Backend.serialize() orchestrates the
sub-stores. SqliteStore splits _create_backend into a create path (live
objects) and a load path (deserialized config). Includes automatic
migration from the legacy three-column schema.
* move ABCs from type/backend.py into their own dirs, rename livechannel → notifier
Each abstract base class now lives as base.py in its implementation
directory: blobstore/base.py, vectorstore/base.py, observationstore/base.py,
notifier/base.py. type/backend.py is deleted. livechannel/ is renamed to
notifier/ with a backwards-compat shim so old serialized registry entries
still resolve via importlib.
* move serialize() to base classes, drop deserialize() in favor of constructor
serialize() is now a concrete method on BlobStore, VectorStore, and Notifier
base classes — implementations inherit it via self._config.model_dump().
deserialize() classmethods are removed entirely; deserialize_component() in
registry.py calls cls(**config) directly. Backend.deserialize() is also
removed (unused — _assemble_backend handles reconstruction).
* move _create_backend to Store base, MemoryStore becomes empty subclass
Store._create_backend is now concrete — resolves codec, instantiates
components (class → instance or uses instance directly), builds Backend.
StoreConfig holds typed component fields (class or instance) with in-memory
defaults. codec removed from StoreConfig (per-stream concern, not store-level).
MemoryStore is now just `pass` — inherits everything from Store.
SqliteStore overrides _create_backend to inject conn-shared components
and registry persistence, then delegates to super().
* move connection init from __init__ to start(), make ObservationStore a Resource
SQLite components (BlobStore, VectorStore, ObservationStore) now defer
connection opening and table creation to start(). __init__ stores config
only. Store._create_backend and SqliteStore._create_backend call start()
on all components they instantiate. ObservationStore converted from
Protocol to CompositeResource base class so all observation stores
inherit start()/stop() lifecycle.
* rename impl/ → store/, move store.py → store/base.py
All store-related code now lives under store/: base class in base.py,
MemoryStore in memory.py, SqliteStore in sqlite.py. store/__init__.py
re-exports public API. Also renamed test_impl.py → test_store.py.
* remove section separator comments from memory2/
* remove __init__.py re-exports, use direct module imports
Subdirectory __init__.py files in memory2/ were re-exporting symbols
from their submodules. Replace all imports with direct module paths
(e.g. utils.sqlite.open_sqlite_connection instead of utils) and
empty out the __init__.py files.
* delete livechannel/ backwards-compat shim
* simplify RegistryStore: drop legacy schema migration
Replace _migrate_or_create with CREATE TABLE IF NOT EXISTS.
* use context managers in standalone component tests
Replace start()/try/finally/stop() with `with` statements.
* delete all __init__.py files from memory2/
No code imports from package-level; all use direct module paths.
Python 3.3+ implicit namespace packages make these unnecessary.
* make all memory2 sub-store components Configurable
Migrate BlobStore, VectorStore, ObservationStore, Notifier, and
RegistryStore to use the Configurable[ConfigT] mixin pattern,
matching the existing Store class. Runtime deps (conn, codec) use
Field(exclude=True) so serialize()/model_dump() skips them.
All call sites updated to keyword args.
* add open_disposable_sqlite_connection and use it everywhere
Centralizes the pattern of opening a SQLite connection paired with a
disposable that closes it, replacing manual Disposable(lambda: conn.close())
at each call site.
* add StreamAccessor for attribute-style stream access on Store
* small cleanups: BlobStore.delete raises KeyError on missing, drop _MISSING sentinel
* checkout mapping/occupancy/gradient.py from dev
* limit opencv threads to 2 by default, checkout worker.py from dev
* test for magic accessor
* ci/pr comments
* widen flaky pointcloud AABB tolerance from 0.1 to 0.2
The test_detection3dpc test fails intermittently in full suite runs
due to non-deterministic point cloud boundary values.
* suppress mypy false positive on scipy distance_transform_edt return type
* ci test fixes
* sam mini PR comments
* replace Generator[T, None, None] with Iterator[T] in memory2 tests
* fix missing TypeVar import in subject.py
* skipping turbojpeg stuff in CI
* removed db from lfs for now
* turbojpeg
* removed redundant rerun teleop methods * teleop blueprints rename * pre-commit fixes * fix: phone teleop import * fix: comments
* event based sub callback collector for tests * shorter wait for no msg * fix(tests): raise AssertionError on CallbackCollector timeout Instead of silently returning when messages never arrive, wait() now raises with a clear message showing expected vs received count.
* feat: adding arm_ip and can_port to env * feat: using env variables in blueprints * arm_ip env variables * misc: control blueprints cleanup * refactor: hardware factories * fix: pre-commit checks * fix: gripper check + comments * fix: gripper addition * fix: no init needed, blueprint path * CI code cleanup * check trigger commit * fix: unwanted changes * fix: blueprint path * fix: remove duplicates * feat: env var from globalconfig
* fix(cli): speed up `dimos --help` by extracting lightweight type aliases Move NavigationStrategy and VlModelName type aliases into dimos/core/types.py so that global_config.py no longer pulls in matplotlib/scipy (via path_map.py) or torch/langchain (via create.py) at import time. Original modules re-export from the new file so existing imports continue to work. `dimos --help` drops from ~3-4s to ~1.9s. * fix: move type aliases to their respective packages NavigationStrategy → dimos/mapping/occupancy/types.py VlModelName → dimos/models/vl/types.py Remove dimos/core/types.py * test: add CLI startup speed regression test Guards against heavy imports (matplotlib, torch, scipy) leaking into the CLI entrypoint via GlobalConfig. Fails if dimos --help takes >8s. * CI code cleanup * fix: exclude .venv and other non-source dirs from doclinks file index build_file_index now skips paths rooted in .venv, node_modules, __pycache__, or .git. Fixes test_excludes_venv failure when .venv is a symlink (not matched by gitignore trailing-slash patterns). * Revert "fix: exclude .venv and other non-source dirs from doclinks file index" This reverts commit 61f8588. --------- Co-authored-by: jeff-hykin <17692058+jeff-hykin@users.noreply.github.com>
Co-authored-by: s <pomichterstash@gmail.com> Co-authored-by: jeff-hykin <17692058+jeff-hykin@users.noreply.github.com>
Co-authored-by: Sam Bull <Sam.B@snowfalltravel.com>
Authored by vrinek
Co-authored-by: Sam Bull <Sam.B@snowfalltravel.com>
Co-authored-by: Jeff Hykin <jeff.hykin@gmail.com>
Co-authored-by: leshy <lesh@sysphere.org>
There was a problem hiding this comment.
Pull request overview
This PR modernizes DimOS module wiring and configuration typing while tightening network/security defaults and updating imports across mapping, manipulation, hardware, and agent subsystems.
Changes:
- Refactors many modules to use typed
Module[Config]+pydantic.Fielddefaults and updates import paths to “leaf” message modules (e.g.,...Pose import Pose). - Migrates blueprint building/coordination patterns toward
dimos.core.coordination(ModuleCoordinator.build(...)) and MCP-based agent composition (McpServer+McpClient). - Introduces/adjusts new APIs and utilities (e.g., navigation map
gradient_strategy, new specs/protocols, new adapters/tests, safer localhost binding defaults).
Reviewed changes
Copilot reviewed 243 out of 744 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| dimos/mapping/utils/distance.py | Switches LatLon import to models namespace. |
| dimos/mapping/test_voxels.py | Updates message import path for PointCloud2. |
| dimos/mapping/pointclouds/test_occupancy_speed.py | Fixes TimedSensorReplay import to replay module. |
| dimos/mapping/pointclouds/test_occupancy.py | Updates sensor_msgs PointCloud2 import style. |
| dimos/mapping/pointclouds/occupancy.py | Updates Pose/PointCloud2 imports to leaf modules. |
| dimos/mapping/pointclouds/demo.py | Uses leaf imports for OccupancyGrid/PointCloud2. |
| dimos/mapping/osm/test_osm.py | Switches LatLon import to models namespace. |
| dimos/mapping/osm/query.py | Adds Any typing + generics for VlModel, updates LatLon import. |
| dimos/mapping/osm/osm.py | Moves mapping types to models + leaf Image imports. |
| dimos/mapping/osm/demo_osm.py | Updates agent composition to MCP server/client + blueprint style. |
| dimos/mapping/osm/current_location_map.py | Uses VlModel[Any] typing and LatLon from models. |
| dimos/mapping/occupancy/visualize_path.py | Updates Path import to leaf module. |
| dimos/mapping/occupancy/visualizations.py | Updates Path import to leaf module. |
| dimos/mapping/occupancy/types.py | Replaces TFMessage export with NavigationStrategy type alias definition. |
| dimos/mapping/occupancy/test_path_resampling.py | Updates Pose import to leaf module. |
| dimos/mapping/occupancy/test_path_mask.py | Updates Pose/Image imports to leaf modules. |
| dimos/mapping/occupancy/test_path_map.py | Updates test to pass new gradient_strategy arg. |
| dimos/mapping/occupancy/path_resampling.py | Replaces bulk imports with leaf imports for messages. |
| dimos/mapping/occupancy/path_mask.py | Updates Path import to leaf module. |
| dimos/mapping/occupancy/path_map.py | Adds gradient_strategy parameter + strategy routing. |
| dimos/mapping/occupancy/gradient.py | Adds GradientStrategy alias + improves typing around distance transform. |
| dimos/mapping/google_maps/test_google_maps.py | Switches LatLon import to models namespace. |
| dimos/mapping/google_maps/google_maps.py | Moves google maps types to models; updates LatLon import. |
| dimos/mapping/costmapper.py | Converts config defaults to pydantic Field; uses Module[Config] generics. |
| dimos/manipulation/test_manipulation_unit.py | Updates RobotModelConfig path field name + message imports. |
| dimos/manipulation/test_manipulation_module.py | Updates RobotModelConfig + message imports; renames urdf_path→model_path usage. |
| dimos/manipulation/planning/utils/path_utils.py | Updates JointState import + refactors TYPE_CHECKING imports. |
| dimos/manipulation/planning/utils/mesh_utils.py | Replaces xacro monkey-patching with shared process_xacro helper. |
| dimos/manipulation/planning/utils/kinematics_utils.py | Refactors Jacobian import path. |
| dimos/manipulation/planning/utils/init.py | Removes package re-export barrel for planning utils. |
| dimos/manipulation/planning/trajectory_generator/spec.py | Updates JointTrajectory import to leaf module. |
| dimos/manipulation/planning/trajectory_generator/joint_trajectory_generator.py | Updates trajectory message imports to leaf modules. |
| dimos/manipulation/planning/spec/protocols.py | Refactors spec type imports; adds get_obstacles to WorldSpec. |
| dimos/manipulation/planning/spec/models.py | Updates PoseStamped/JointState imports; trims section comments. |
| dimos/manipulation/planning/spec/config.py | Migrates RobotModelConfig to ModuleConfig w/ pydantic defaults and model_path. |
| dimos/manipulation/planning/spec/init.py | Removes spec barrel export module. |
| dimos/manipulation/planning/planners/rrt_planner.py | Refactors spec imports + JointState leaf import; comment cleanup. |
| dimos/manipulation/planning/planners/init.py | Removes planners barrel export module. |
| dimos/manipulation/planning/monitor/world_state_monitor.py | Updates JointState import and WorldSpec import path. |
| dimos/manipulation/planning/monitor/world_obstacle_monitor.py | Refactors imports; changes default use_mesh_obstacles; adds remove_object_obstacle. |
| dimos/manipulation/planning/monitor/init.py | Removes monitor barrel export module. |
| dimos/manipulation/planning/kinematics/pinocchio_ik.py | Leaf imports for Pose types; comment cleanup. |
| dimos/manipulation/planning/kinematics/jacobian_ik.py | Refactors spec imports; leaf imports for messages; comment cleanup. |
| dimos/manipulation/planning/kinematics/drake_optimization_ik.py | Refactors spec imports; leaf imports for PoseStamped/Transform/JointState. |
| dimos/manipulation/planning/kinematics/init.py | Removes kinematics barrel export module. |
| dimos/manipulation/planning/factory.py | Updates TYPE_CHECKING protocol imports. |
| dimos/manipulation/planning/examples/manipulation_client.py | Leaf imports; preserves EE orientation when rpy not provided. |
| dimos/manipulation/planning/examples/init.py | Removes examples barrel module. |
| dimos/manipulation/planning/init.py | Removes planning module lazy-loader export surface. |
| dimos/manipulation/planning/README.md | Renames config field to model_path in docs. |
| dimos/manipulation/manipulation_interface.py | Comment cleanup only. |
| dimos/manipulation/grasping/grasping.py | Moves RPC dependencies to typed Specs; leaf imports; removes blueprint alias exports. |
| dimos/manipulation/grasping/graspgen_module.py | Migrates to docker module config; adjusts Module generics and typing; removes all. |
| dimos/manipulation/grasping/grasp_gen_spec.py | Replaces stale docstring with GraspGenSpec protocol. |
| dimos/manipulation/grasping/demo_grasping.py | Updates blueprint composition to MCP + class blueprints. |
| dimos/manipulation/grasping/init.py | Removes grasping barrel exports. |
| dimos/manipulation/control/trajectory_controller/spec.py | Updates TYPE_CHECKING imports to leaf modules. |
| dimos/manipulation/control/trajectory_controller/joint_trajectory_controller.py | Converts to Module[Config] and uses shared join timeout constant. |
| dimos/manipulation/control/trajectory_controller/init.py | Removes trajectory_controller barrel exports. |
| dimos/manipulation/control/servo_control/init.py | Removes servo_control barrel exports. |
| dimos/manipulation/control/coordinator_client.py | Leaf imports; comment cleanup. |
| dimos/manipulation/control/arm_driver_spec.py | Adds ArmDriverSpec protocol for FK/IK RPC surface. |
| dimos/manipulation/control/init.py | Removes manipulation control barrel exports. |
| dimos/manipulation/init.py | Removes manipulation barrel exports. |
| dimos/hardware/sensors/lidar/livox/module.py | Updates coordination imports; converts to generic NativeModule; removes blueprint alias exports. |
| dimos/hardware/sensors/lidar/livox/livox_blueprints.py | Updates blueprint composition + rerun bridge module naming. |
| dimos/hardware/sensors/lidar/fastlio2/module.py | Migrates config path handling to pydantic pipeline; generic NativeModule; removes blueprint alias exports. |
| dimos/hardware/sensors/lidar/fastlio2/fastlio_blueprints.py | Updates coordination + rerun bridge blueprint usage. |
| dimos/hardware/sensors/fake_zed_module.py | Converts to Module[Config] pattern, leaf imports, replay import fix. |
| dimos/hardware/sensors/camera/zed/test_zed.py | Skips ZED test when SDK missing; imports compat layer explicitly. |
| dimos/hardware/sensors/camera/zed/compat.py | Adds SDK detection layer + safe stubs; removes zed_camera export. |
| dimos/hardware/sensors/camera/zed/camera.py | Converts config defaults to pydantic Field; shared join timeout; updates ModuleCoordinator import. |
| dimos/hardware/sensors/camera/webcam.py | Leaf imports for CameraInfo/Image. |
| dimos/hardware/sensors/camera/spec.py | Refactors config/type base classes and service imports. |
| dimos/hardware/sensors/camera/realsense/camera.py | Converts config defaults to pydantic Field; shared join timeout; removes blueprint alias exports. |
| dimos/hardware/sensors/camera/realsense/init.py | Removes lazy-loader export pattern. |
| dimos/hardware/sensors/camera/module.py | Converts CameraModuleConfig defaults to pydantic Field; updates blueprint usage. |
| dimos/hardware/sensors/camera/gstreamer/gstreamer_sender.py | Defaults listen host to localhost for safer networking; updates CLI docs. |
| dimos/hardware/sensors/camera/gstreamer/gstreamer_camera_test_script.py | Updates ModuleCoordinator import + pubsub autoconf path. |
| dimos/hardware/sensors/camera/gstreamer/gstreamer_camera.py | Converts to Module[Config], moves params into config, uses shared join timeout. |
| dimos/hardware/manipulators/xarm/adapter.py | Comment cleanup only. |
| dimos/hardware/manipulators/spec.py | Leaf imports and comment cleanup for adapter protocol. |
| dimos/hardware/manipulators/sim/adapter.py | Adds MuJoCo simulation adapter + registry registration hook. |
| dimos/hardware/manipulators/registry.py | Reworks adapter discovery to directory scan (adapter.py presence). |
| dimos/hardware/manipulators/piper/adapter.py | Comment cleanup only. |
| dimos/hardware/manipulators/mock/init.py | Removes mock adapter barrel file. |
| dimos/hardware/manipulators/init.py | Removes manipulators barrel export module. |
| dimos/hardware/drive_trains/spec.py | Comment cleanup only. |
| dimos/hardware/drive_trains/registry.py | Reworks discovery to filesystem scan; allows callable adapters. |
| dimos/hardware/drive_trains/mock/adapter.py | Comment cleanup only. |
| dimos/hardware/drive_trains/flowbase/adapter.py | Comment cleanup only. |
| dimos/hardware/drive_trains/flowbase/init.py | Removes flowbase barrel file. |
| dimos/experimental/security_demo/conftest.py | Adds fixtures for security demo testing with extensive mocking. |
| dimos/e2e_tests/test_spatial_memory.py | Updates MCP RPC topic naming. |
| dimos/e2e_tests/test_simulation_module.py | Removes simulation module e2e tests file. |
| dimos/e2e_tests/test_security_module.py | Adds MCP-backed security module e2e test. |
| dimos/e2e_tests/test_scan_and_follow_person.py | Updates MCP RPC topic naming. |
| dimos/e2e_tests/test_person_follow.py | Updates MCP RPC topic naming. |
| dimos/e2e_tests/test_patrol_and_follow.py | Adds patrol+follow e2e test flow. |
| dimos/e2e_tests/test_dimos_cli_e2e.py | Updates MCP RPC topic naming in CLI e2e. |
| dimos/e2e_tests/test_control_coordinator.py | Leaf imports for JointState / trajectory messages. |
| dimos/e2e_tests/lcm_spy.py | Switches DimosMsg import location + PoseStamped leaf import. |
| dimos/e2e_tests/conftest.py | Adds explore_office fixtures using DirectCmdVelExplorer; leaf imports updates. |
| dimos/core/worker_manager.py | Removes old WorkerManager implementation (moved to coordination managers). |
| dimos/core/transport.py | Defers jpeg-related imports to avoid heavy dependency import cost at startup. |
| dimos/core/tests/stress_test_blueprint.py | Updates autoconnect import path. |
| dimos/core/tests/demo_mcp_killtest.py | Updates coordination imports; uses ModuleCoordinator.build. |
| dimos/core/testing.py | Updates joins to shared timeout; leaf imports; Module init kwargs. |
| dimos/core/test_stream.py | Fixes type annotations and Module init kwargs; leaf imports. |
| dimos/core/test_rpcstress.py | Updates ModuleCoordinator import path. |
| dimos/core/test_native_module.py | Updates build pattern; adds thread cleanup to reduce flakiness. |
| dimos/core/test_mcp_integration.py | Updates autoconnect + ModuleCoordinator.build usage; comment cleanup. |
| dimos/core/test_global_config.py | Replaces incorrect content with GlobalConfig security default tests. |
| dimos/core/test_daemon.py | Updates health_check tests to match manager-based coordinator. |
| dimos/core/test_core.py | Updates imports and expected RPC count. |
| dimos/core/test_cli_stop_status.py | Comment cleanup only. |
| dimos/core/run_registry.py | Moves signal import to top-level. |
| dimos/core/rpc_client.py | Updates RPC plumbing to new worker proxy + rpc timeout configuration. |
| dimos/core/resource_monitor/stats.py | Updates ttl_cache import path. |
| dimos/core/resource_monitor/init.py | Removes resource_monitor barrel exports. |
| dimos/core/resource.py | Rebuilds Resource on top of reactivex Disposable + adds context manager + CompositeResource. |
| dimos/core/library_config.py | Adds process-wide default configuration (OpenCV thread limiting). |
| dimos/core/introspection/svg.py | Updates Blueprint import path to coordination module. |
| dimos/core/introspection/module/info.py | Adjusts which RPCs are treated as internal. |
| dimos/core/introspection/module/init.py | Removes introspection module barrel exports. |
| dimos/core/introspection/blueprint/dot.py | Updates Blueprint import path + Module base type usage. |
| dimos/core/introspection/init.py | Removes introspection barrel exports. |
| dimos/core/global_config.py | Tightens defaults (mcp_host localhost); adds xarm ips/can port; adjusts model name typing. |
| dimos/core/daemon.py | Updates ModuleCoordinator typing import + comment cleanup. |
| dimos/core/core.py | Removes eager Open3D pickler registration at import time. |
| dimos/core/coordination/worker_manager_docker.py | Adds Docker deployment worker manager implementation. |
| dimos/core/coordination/worker_manager.py | Introduces WorkerManager protocol abstraction. |
| dimos/core/coordination/python_worker.py | Renames Worker→PythonWorker; injects GlobalConfig; applies library config in worker. |
| dimos/core/conftest.py | Updates ModuleCoordinator import path. |
| dimos/control/tick_loop.py | Uses shared thread join timeout; leaf import update. |
| dimos/control/test_control.py | Leaf imports for trajectory messages; comment cleanup. |
| dimos/control/tasks/velocity_task.py | Comment cleanup only. |
| dimos/control/tasks/trajectory_task.py | Leaf imports for trajectory messages; comment cleanup. |
| dimos/control/tasks/teleop_task.py | Leaf imports for pose types; comment cleanup. |
| dimos/control/tasks/servo_task.py | Comment cleanup only. |
| dimos/control/tasks/cartesian_ik_task.py | Leaf imports for pose types; comment cleanup. |
| dimos/control/tasks/init.py | Removes tasks barrel exports. |
| dimos/control/task.py | Leaf imports for pose types; comment cleanup. |
| dimos/control/examples/twist_base_keyboard_teleop.py | Updates blueprint build to ModuleCoordinator.build; KeyboardTeleop class blueprint. |
| dimos/control/examples/cartesian_ik_jogger.py | Leaf import for PoseStamped in runtime import locations. |
| dimos/control/components.py | Adds adapter_kwargs for hardware component configuration. |
| dimos/control/blueprints/mobile.py | Adds mobile manipulation coordinator blueprints. |
| dimos/control/blueprints/dual.py | Adds dual-arm coordinator blueprints using new GlobalConfig fields. |
| dimos/control/init.py | Removes control module barrel exports. |
| dimos/control/README.md | Updates blueprint usage example to ControlCoordinator.blueprint. |
| dimos/constants.py | Introduces shared DEFAULT_THREAD_JOIN_TIMEOUT constant. |
| dimos/conftest.py | Updates ModuleCoordinator import path. |
| dimos/agents_deprecated/prompt_builder/impl.py | Comment cleanup only. |
| dimos/agents_deprecated/modules/gateway/init.py | Removes gateway barrel exports. |
| dimos/agents_deprecated/modules/base_agent.py | Introduces BaseAgentConfig ModuleConfig and Module[Config] usage. |
| dimos/agents_deprecated/modules/base.py | Updates UnifiedGatewayClient import paths. |
| dimos/agents_deprecated/memory/image_embedding.py | Suppresses missing onnxruntime import error for typing. |
| dimos/agents_deprecated/agent.py | Comment cleanup only. |
| dimos/agents/web_human_input.py | Uses shared thread join timeout; removes blueprint alias exports. |
| dimos/agents/vlm_stream_tester.py | Switches to VLMAgentSpec injection and shared join timeout; leaf Image import. |
| dimos/agents/vlm_agent_spec.py | Adds VLMAgentSpec protocol. |
| dimos/agents/vlm_agent.py | Converts to Module[VLMAgentConfig]; leaf Image import; removes blueprint alias exports. |
| dimos/agents/skills/test_unitree_skill_container.py | Adds stub modules to satisfy RPC dependencies during tests. |
| dimos/agents/skills/test_gps_nav_skills.py | Adds StubWebsocketVis and updates LatLon import to models. |
| dimos/agents/skills/test_google_maps_skill_container.py | Updates imports; Module init kwargs; LatLon moved to models. |
| dimos/agents/skills/speak_skill_spec.py | Replaces stale re-export with SpeakSkillSpec protocol. |
| dimos/agents/skills/speak_skill.py | Adds non-blocking speech mode and thread tracking. |
| dimos/agents/skills/osm.py | Updates LatLon import to models and removes blueprint alias exports. |
| dimos/agents/skills/gps_nav_skill.py | Switches to WebsocketVisSpec dependency instead of manual RpcCall wiring. |
| dimos/agents/skills/google_maps_skill_container.py | LatLon import move + Module init kwargs; removes blueprint alias exports. |
| dimos/agents/skills/demo_skill.py | Rebuilds demo skill blueprint using MCP server/client. |
| dimos/agents/skills/demo_robot.py | LatLon import to models; removes blueprint alias exports. |
| dimos/agents/skills/demo_gps_nav.py | Rebuilds demo GPS nav blueprint using MCP server/client. |
| dimos/agents/skills/demo_google_maps_skill.py | Rebuilds demo Google Maps blueprint using MCP server/client. |
| dimos/agents/skills/demo_calculator_skill.py | Removes blueprint alias export wiring. |
| dimos/agents/mcp/test_mcp_client.py | Leaf Image import; reduces per-instance init logic in test modules. |
| dimos/agents/mcp/mcp_server.py | Refactors imports; adds explicit concurrent.futures; introduces thread-safety TODO note. |
| dimos/agents/mcp/mcp_adapter.py | Comment cleanup only. |
| dimos/agents/mcp/conftest.py | Updates build to ModuleCoordinator.build. |
| dimos/agents/mcp/README.md | Updates CLI invocation to new agentic blueprint name. |
| dimos/agents/fixtures/test_prompt.json | Removes fixture JSON file. |
| dimos/agents/fixtures/test_multiple_tool_calls_with_multiple_messages.json | Removes fixture JSON file. |
| dimos/agents/fixtures/test_image.json | Removes fixture JSON file. |
| dimos/agents/fixtures/test_can_call_tool.json | Removes fixture JSON file. |
| dimos/agents/fixtures/test_can_call_again_on_error.json | Removes fixture JSON file. |
| dimos/agents/demo_agent.py | Rebuilds demo agent blueprints using MCP and CameraModule blueprint. |
| dimos/agents/conftest.py | Switches test harness to MCP client/server and ModuleCoordinator.build. |
| dimos/agents/agent_test_runner.py | Migrates messages into ModuleConfig; switches AgentSpec import path. |
| dimos/agents/agent_spec.py | Adds AgentSpec protocol. |
| data/.lfs/xarm6.tar.gz | Adds Git LFS pointer for xarm6 artifact. |
| data/.lfs/unity_sim_x86.tar.gz | Adds Git LFS pointer for unity simulator artifact. |
| data/.lfs/security_no_detection.png.tar.gz | Adds Git LFS pointer for security fixture image artifact. |
| data/.lfs/security_detection.png.tar.gz | Adds Git LFS pointer for security fixture image artifact. |
| data/.lfs/piper.tar.gz | Adds Git LFS pointer for piper artifact. |
| data/.lfs/go2_bigoffice.db.tar.gz | Adds Git LFS pointer for database artifact. |
| README.md | Updates CLI docs and blueprint example to MCP-based wiring. |
| .github/workflows/tests.yml | Adds workflow timeout to avoid runaway CI jobs. |
| .github/workflows/stale.yml | Adds stale PR automation workflow. |
| .github/ISSUE_TEMPLATE/spec.yml | Adds a “Spec” issue template for technical design docs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| occupancy_grid: OccupancyGrid, | ||
| robot_width: float, | ||
| strategy: NavigationStrategy, | ||
| gradient_strategy: GradientStrategy, |
There was a problem hiding this comment.
This change makes gradient_strategy a required parameter even though the previous behavior implicitly used voronoi_gradient. If avoiding a breaking API change is required, give gradient_strategy a default (e.g., defaulting to the previous behavior) so existing call sites keep working while still allowing overrides.
| gradient_strategy: GradientStrategy, | |
| gradient_strategy: GradientStrategy = "voronoi", |
| try: | ||
| generate = self.get_rpc_calls("GraspGenModule.generate_grasps") | ||
| result = generate(pc, scene_pc) | ||
| result = self._grasp_gen.generate_grasps(pc, scene_pc) |
There was a problem hiding this comment.
self._grasp_gen and self._scene_registration are now used directly, but this diff doesn’t show them being initialized in __init__/start(). If these are not guaranteed to be injected by the framework before use, this will raise AttributeError at runtime. A concrete fix is to initialize them explicitly during start() (e.g., by resolving them from system modules / dependency injection) and raise a clear error if not available.
| "ObjectSceneRegistrationModule.get_object_pointcloud_by_name" | ||
| ) | ||
| return get_pc(object_name) # type: ignore[no-any-return] | ||
| return self._scene_registration.get_object_pointcloud_by_object_id(object_id) # type: ignore[no-any-return] |
There was a problem hiding this comment.
self._grasp_gen and self._scene_registration are now used directly, but this diff doesn’t show them being initialized in __init__/start(). If these are not guaranteed to be injected by the framework before use, this will raise AttributeError at runtime. A concrete fix is to initialize them explicitly during start() (e.g., by resolving them from system modules / dependency injection) and raise a clear error if not available.
|
|
||
| # Convert to meters and clip to max distance | ||
| distance_meters = np.clip(distance_cells * occupancy_grid.resolution, 0, max_distance) | ||
| distance_meters = np.clip(distance_cells * occupancy_grid.resolution, 0, max_distance) # type: ignore[operator] |
There was a problem hiding this comment.
The # type: ignore[operator] on the distance_cells * occupancy_grid.resolution expression suggests OccupancyGrid.resolution isn’t typed as a numeric scalar. Instead of ignoring the operator error here, prefer fixing the type at the source (e.g., ensure resolution is typed as float) or cast locally (e.g., float(occupancy_grid.resolution)) so type checking remains meaningful.
| distance_meters = np.clip(distance_cells * occupancy_grid.resolution, 0, max_distance) # type: ignore[operator] | |
| distance_meters = np.clip(distance_cells * float(occupancy_grid.resolution), 0, max_distance) |
| @pytest.fixture | ||
| def direct_cmd_vel_explorer() -> Generator[PersonTrackPublisher, None, None]: | ||
| explorer = DirectCmdVelExplorer() | ||
| explorer.start() | ||
| yield explorer | ||
| explorer.stop() |
There was a problem hiding this comment.
The fixture return annotation is Generator[PersonTrackPublisher, ...] but the yielded object is a DirectCmdVelExplorer. This is a concrete type mismatch that can hide real errors (and can break strict type-checking). Update the annotation to Generator[DirectCmdVelExplorer, None, None] (or a compatible protocol/base type).
| from dimos.core.coordination.blueprints import autoconnect | ||
|
|
||
| autoconnect( | ||
| from dimos.core.coordination.module_coordinator import ModuleCoordinator | ||
| ModuleCoordinator.build(autoconnect( | ||
| Mid360.blueprint(host_ip="192.168.1.5"), | ||
| SomeConsumer.blueprint(), | ||
| ).build().loop() | ||
| )).loop() |
There was a problem hiding this comment.
The usage snippet appears to have mismatched parentheses: ModuleCoordinator.build(autoconnect(... )).loop() implies build() returns a coordinator that has loop(), but the example formatting currently makes it hard to verify correctness at a glance. Please adjust the example to a clearly valid call structure (and ensure it matches the actual ModuleCoordinator.build(...) return type and how users should run the coordinator).
| def on_system_modules(self, modules: list[RPCClient]) -> None: | ||
| # TODO: this is a bit hacky, also not thread-safe | ||
| assert self.rpc is not None | ||
| app.state.skills = [ |
There was a problem hiding this comment.
The code acknowledges on_system_modules mutates app.state in a way that is not thread-safe. Because MCP requests can be served concurrently, this can lead to races (partially updated skills/rpc_calls). A tangible fix is to protect updates with a lock (e.g., a module-level threading.Lock) and to assign fully-built new dict/list objects atomically under that lock.
No description provided.