Labs vs libraries¶
The
example-librarynames in the examples below are synthetic documentation fixtures. MAS-Lab does not ship anexample-libraryor anioclibrary.
Labs, libraries, and local plugins¶
A lab is an experiment pack. A library is reusable code and YAML. Do not turn a lab into a library, and do not create a library when you only need an experiment.
Datasets. library-samples publishes the complete reusable pack for the
reference app (trip-planner-benchmark). CI, unit tests, and functional
tests pin that catalog (locator: samples) and cap rows with
dataset.limit. They must not path: into labs/ — paper labs are not
shipped with the packages. Experiment-specific packs (QA reasoning, MAS
necessity, lifecycle queries, extensions) live under that lab’s datasets/
and are referenced only from the lab itself.
Developer discovery contract: library-discovery.md.
Lab¶
A lab is a *.lab/ folder with lab-config.yaml. It stays flat: scenarios,
overlays, datasets, and pipelines. Refs use name:path (for example
samples:tools/calc.tool.yaml).
Paper labs live under labs/. Create a lab when you are
composing a campaign, not when you are publishing reusable tools.
Library¶
A library is a folder with library.yaml. Apps, tools, overlays, plugins,
and Python live there. In a name:path ref, name is always a library
name (samples, standard, lab, skills, ioa, or a lab-local name
such as lib). It is never a filesystem path. Unknown names fail.
Shipped libraries in this repo include library-samples/,
library-standard/, library-lab/, library-skills/, and library-ioa/.
The name you write in YAML is a library scheme (samples, example-library),
not necessarily the Python package name (mas-library-samples). Additional
names can be listed as aliases: in library.yaml; the directory basename
and name: field are also accepted. Labs then pin a MAS with
library:app (for example example-library:my-app@v2). Versioning uses
name@version (bare name is @latest). Slash is a path
(example-library:apps/my-app/v2), not an id alias.
How to write those refs: writing-manifests.md.
A library may live inside a lab. That does not make the lab itself a
library — do not put library.yaml on the lab root.
Local plugins¶
A plugin is a runtime or pipeline extension registered by a library. Put plugin Python and YAML in a library (lab-local or shipped). Do not invent a third top-level “plugins folder” beside lab vs library.
| What you are adding | Where it lives |
|---|---|
| One-off bench/pipeline step for this experiment | That lab’s local library (catalogued in library.yaml) |
| Agent/runtime plugin (design pattern, memory, tool provider, …) | Declared in that library’s library.yaml so discovery finds it |
| Experiment pack (scenarios, overlays, lab-owned datasets) | The lab, not a library |
A pipeline step is still a plugin of type step. The lab is the experiment
surface; the library is what registers the step.
Enable without editing agent YAML. Workspace config.yaml plugins: and
lab.enable_plugins turn on runtime plugins (gdb, checkpoint stores).
Every catalog entry is commented in the init template — uncomment to enable.
spec.observability and spec.governance stay on the agent.
When to use which¶
- Lab is sufficient when you only compose existing libraries: experiments,
overlays, datasets, refs like
samples:tools/calc.tool.yaml. No new reusable code. - Local library inside the lab when this lab needs reusable manifests,
tools, plugins, or code that are not (yet) worth a shipped package. Put
them in a subdir with
library.yaml, list it inlab.libraries, ref asname:path. - Shipped / workspace library when more than one lab (or ctl/runtime
generally) should reuse it: an installable package, or a path in workspace
config.yamlmanifest_libraries:. - Local plugins live inside a library (option 2 or 3), not instead of
one. If it is only a bench step for this experiment, keep it in the lab’s
local library. If it is an agent/runtime plugin, declare it in that
library’s
library.yaml.
Lab-local library (in-repo pattern)¶
labs/lifecycle-control.lab and labs/extensions.lab keep reusable pipeline
code in a package named after the lab and list that directory:
# lab-config.yaml
lab:
name: lifecycle-control
libraries:
- lifecycle_control_lab/
# lifecycle_control_lab/library.yaml
apiVersion: mas/v1
kind: Library
name: lifecycle-control-lib
description: Lab-local pipeline figure steps for this lab.
version: "0.1.0"
The library name in refs is the listed basename:
lifecycle_control_lab/ → lifecycle_control_lab. Immediate children of the
lab root that contain library.yaml are picked up too.
The directory is also the Python package (lifecycle_control_lab.steps.…).
Every library's parent directory shares one sys.path, so package names must
be unique across the libraries a process loads: two labs that both ship a
lib/ package would shadow each other. The plugin registry fails with both
paths when it detects such a clash.
A listed directory without library.yaml is Python sys.path only. Do
not leave an in-repo lab in that state.
How to write name:path¶
# Overlay / experiment / agent — prefix is a library name
tools:
- samples:tools/calc.tool.yaml
application:
app: example-library:my-app@v2
# or: manifest: samples:apps/trip-planner/mas.yaml
# Workspace config.yaml — search folders (library root or parent of libraries)
manifest_libraries:
- .
- ./libraries
Lab-local names win over the same name in workspace config or an installed library. First-seen name wins.
lab.libraries, workspace manifest_libraries, and MAS_LIBRARY_PATHS are
the same scan. Install (entry point) is the other door. library.yaml
fills the catalog. Do not declare aliases (ioc for example-library).
See also¶
- How to write manifests — inline vs file vs
LIBRARY:id - User configuration — workspace
config.yamland path vars - Lab manifests —
lab-config.yamlfields - Tutorial 1 — overlay
name:pathrefs - Package map — installable wheels
- Library discovery — search order and
library.yamlcontract