Resources
Declare bounded-concurrency resource pools in factory.json and consume them from workstation requirements while a dispatch is in flight.
Where Requirements Belong
A resource pool is a shared concurrency limit. Declare it once under top-level resources[] with at least {name, capacity}, then consume it from workstations[].resources[] so the workstation holds capacity while the dispatch is in flight. The same pool name means one shared limit across every requirement that references it. Use this ownership split when you decide where to declare a pool and where to consume capacity.| Location | Shared shape | What to use it for |
|---|---|---|
| resources[] | yes — {name, capacity} plus optional typed metadata | Declare the pool name and total available capacity |
| workstations[].resources[] | yes — matching requirement shape | Consume capacity for a workflow step while that workstation runs |
| workers[].resources[] | yes — matching requirement shape | Worker-runtime requirement metadata only; not the canonical workflow-step concurrency path |
Worker-only resources are not the canonical explanation for workflow-step concurrency. Put the scheduling-facing requirement on the workstation. Keep workers[].resources[] only when the worker-runtime contract itself needs the same requirement metadata.
Runtime-capacity resources are not portability supportingFiles. Do not overload a capacity pool with bundled files or external tool checks; supportingFiles belong to the portability contract, not to bounded concurrency.
Minimal Bounded-Concurrency Example
This minimal factory fragment declares one shared pool and one workstation requirement. Copy it when you need the smallest readable capacity example before adding typed metadata.Read the example as runtime capacity, not decoration: resources[0] declares a pool named agent-slot with total available capacity 2. workstations[0].resources[0] asks that workstation to hold one slot while the dispatch is in flight. Up to two matching dispatches can run at once; later matching dispatches wait until capacity is released.
Validation rules you must not miss: requirement names must match a declared top-level pool; requirement capacity must be positive; the same pool name means one shared limit everywhere it is referenced.
Typed Resources
Use an uppercase type plus typed metadata when the resource is more than a generic capacity pool. The three typed kinds below are the web-reference set for model-backed and provider-backed limits.| Type | What it bounds | Metadata you need |
|---|---|---|
| MODEL | Local managed model assets and loaded-handle capacity | Requires model (managed runtime identity), backend, and loadPolicy |
| PROVIDER_QUOTA | Provider-wide cloud quota or request budget | Requires provider and model |
| INVOCATION_SLOT | Per-model or per-provider concurrency | Carry the provider or model identity the scheduler should throttle |
Stay on the generic {name, capacity} shape when you only need a shared concurrency pool. Switch to a typed resource when the pool must identify a managed model asset, a provider quota boundary, or an invocation slot the scheduler should throttle by provider or model.
LOCAL inference workers that depend on managed model assets must reference a matching top-level MODEL resource. Operator commands and full managed-runtime matrices belong on models docs when those pages are published; resources coverage here is the typed resource kinds and the metadata you need to declare them.