Skip to content

MLOps

MLOps brings experiment tracking and run launching into the knowledge base as ordinary pages. A run in MLflow, Weights & Biases, Dagster, or a plain local script becomes an mlops/run page you can link, embed, and query like anything else, and starting a new run is a tool call an agent (or you) can make from a bullet. Nothing about this is a bolt-on dashboard: it is the same page, command model, and outbox that power the rest of Subspace, applied to the “what did my training runs do” problem.

The layer is a plugin stack, not a single monolith. A schema-only contract package defines normalized shapes; a base plugin owns the page types, the ingest workflow, and the views; and each tracker or launcher (MLflow, W&B, Dagster, or a credential-free local mode) is a separate provider plugin that maps its native API onto the contract. You install only the providers you actually use.

@subspace/contract-mlops is a schema-only package, shaped like the task-meta contract used elsewhere in the product: no server logic, just the normalized shapes every provider and every consumer speaks. It defines runSummary, runDetail, metricPoint, launchSpec, launchStatus, capacity, artifactInfo, registeredModel, and runPageMeta (the shape of metadata.mlops on an mlops/run page), plus the capability group constants and validateProviderDeclaration(contract, provides), which the installer runs against a plugin’s manifest before it activates. See contracts and conformance for the full shape reference and the acceptance kit every provider passes.

plugins/mlops-core is the plugin every tracker and launcher provider depends on. It:

  • Declares the mlops/ page types (pageTypes in its manifest): run, experiment, and model, each with a props schema and a default view (mlops-dashboard).
  • Ships the mlops.ingest-runs registered workflow, which wraps a single runTool(mlops.ingest) call so gates, claims, and run-tree rendering behave like any other agent step. Each ingest sweep emits an ('mlops', 'mlops-run-ingested', pageId) outbox event per created or updated run page, the hand-off that Autoresearch and your own triggers subscribe to.
  • Ships mlops-dashboard, a declarative view over the mlops/ directory: a run table (provider, id, status columns) and a by-status board.
  • Ships the mlops-metric-chart viewer, an ESM component bound to the mlops.metrics.history tool that renders a multi-series SVG line chart with a fixed-order categorical legend, shown inline in a run’s step detail. See trackers for the tool it reads.
  • Consumes the mlops.tracker and mlops.launcher contracts through resolveProvider, the same lookup other plugin consumers use: pin a specific provider on a binding page, or let a single enabled provider resolve implicitly; more than one enabled provider for the same contract is a configuration error surfaced at binding time, not a run-time guess.

MLOps splits into two contracts on purpose. A tracker answers “what happened”: it lists runs, fetches detail, and (for providers that declare the capability) streams metric history, artifacts, sweeps, or a model registry. A launcher answers “start this”: submit, status, cancel, and (for providers that declare it) a capacity probe. A provider can implement either, both, or neither symmetrically, for example the filesystem tracker has no launcher counterpart, and the local-runs plugin is a launcher with no tracker.

Every provider plugin declares which contract methods and capability groups it maps in a provides block in its manifest, and the conformance kit is the gate that proves the mapping actually behaves like the contract promises. See contracts and conformance for that gate in detail.

The zero-credential path ships in the box: the filesystem tracker (part of mlops-core) watches any page with metadata.fs.path for a runs/<id>/metrics.json or metrics.jsonl file and materializes it into an mlops/run page, no account or API key required. Its launcher counterpart, plugins/local-runs, spawns bash scripts or Docker containers directly on the host. Together they let you exercise the full MLOps loop, tracking through launching, before you ever point Subspace at MLflow or W&B. See launchers for the bash and Docker lanes.