Skip to content

Design Overview

ModelDock is a management layer that sits above local model runtimes. It does not run inference itself; it orchestrates discovery, download, caching, installation verification, and loading through pluggable runtime adapters.


Layered View

Dependencies point inward — Clean Architecture with SOLID principles:

graph TB
    subgraph Interface["Interface / Delivery Layer"]
        SDK["Python SDK<br/>modeldock/__init__.py"]
        CLI["CLI<br/>modeldock/cli → Typer"]
    end

    subgraph Application["Application / Use-Case Layer"]
        CORE["modeldock/core/<br/>ModelManager · LifecycleOrchestrator<br/>RegistryService · DownloadService<br/>CacheService · ConfigService"]
    end

    subgraph Domain["Domain Layer — pure, no I/O"]
        DOMAIN["modeldock/domain/<br/>Model · ModelSpec · ModelAlias<br/>Capability · Category<br/>RuntimeBackend · Exceptions"]
    end

    subgraph Ports["Port / Abstraction Layer"]
        PORTS["modeldock/ports/<br/>RuntimePort · RegistryPort<br/>DownloaderPort · CachePort<br/>ProgressPort · EventPort"]
    end

    subgraph Adapters["Adapter / Infrastructure Layer"]
        RUNTIMES["runtimes/<br/>ollama · lmstudio<br/>llamacpp · jan · gpt4all · vllm"]
        REGISTRY["registry/<br/>dynamic catalog + bundled fallback"]
        DOWNLOADERS["downloaders/<br/>http · ollama-native pull"]
        CACHE["cache/<br/>filesystem cache"]
        PROGRESS["progress/<br/>rich · tqdm · silent"]
    end

    subgraph Common["Cross-cutting"]
        COMMON["modeldock/common/<br/>config · logging · errors<br/>platform utils · http client"]
    end

    SDK --> CORE
    CLI --> CORE
    CORE --> PORTS
    CORE --> DOMAIN
    PORTS --> RUNTIMES
    PORTS --> REGISTRY
    PORTS --> DOWNLOADERS
    PORTS --> CACHE
    PORTS --> PROGRESS
    COMMON -.-> CORE
    COMMON -.-> ADAPTERS

    style Interface fill:#37474f,stroke:#26a69a,color:#fff
    style Application fill:#455a64,stroke:#26a69a,color:#fff
    style Domain fill:#546e7a,stroke:#26a69a,color:#fff
    style Ports fill:#607d8b,stroke:#26a69a,color:#fff
    style Adapters fill:#78909c,stroke:#26a69a,color:#fff
    style Common fill:#90a4ae,stroke:#26a69a,color:#fff

Key Principle

Domain and ports know nothing about Ollama, HTTP, or the filesystem. The application layer depends only on port interfaces. Concrete runtimes/downloaders are injected (Dependency Inversion).

This is what makes adding LM Studio, vLLM, etc. a matter of writing one new adapter class — no changes to core logic.


Module Responsibilities

Module Responsibility
domain/ Pure entities (no I/O, no framework). Model, ModelSpec, Capability, Category, ModelRef, alias rules.
ports/ typing.Protocol interfaces defining what the system needs from the outside world.
core/ Application services implementing use cases by composing ports.
adapters/runtimes/ Concrete runtime integrations implementing RuntimePort.
adapters/registry/ Searchable model catalog. Dynamic from ollama.com with bundled fallback.
adapters/downloaders/ Moves bytes. Ollama native pull or generic HTTP.
adapters/cache/ Tracks installed/downloaded artifacts. Filesystem manifest + content hashing.
adapters/progress/ Pluggable progress reporters (rich, tqdm, silent).
cli/ Thin delivery layer. Translates argv → core service calls.
common/ Config, logging, platform helpers, shared HTTP client, base errors.

Design Decisions

Decision Rationale Trade-off
Clean Architecture + ports Maximum extensibility for 6 future runtimes More files/abstraction upfront
Return runtime-native client Stay lightweight; don't reimplement inference Less uniform cross-runtime API
Dynamic catalog via HTML scraping Always up-to-date with ollama.com Depends on ollama.com HTML structure
Entry-point plugins Third parties extend without forking Slightly more discovery code
httpx over requests Streaming/resumable downloads, async-ready Extra dep (small, well-maintained)
Optional runtime SDK extras Tiny base install User may need pip install modeldock[ollama]

Next Steps