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.
LocationShared shapeWhat to use it for
resources[]yes — {name, capacity} plus optional typed metadataDeclare the pool name and total available capacity
workstations[].resources[]yes — matching requirement shapeConsume capacity for a workflow step while that workstation runs
workers[].resources[]yes — matching requirement shapeWorker-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.
{
  "resources": [
    { "name": "agent-slot", "capacity": 2 }
  ],
  "workers": [
    { "name": "executor", "type": "AGENT_WORKER" }
  ],
  "workstations": [
    {
      "name": "execute",
      "worker": "executor",
      "inputs": [{ "workType": "story", "state": "init" }],
      "outputs": [{ "workType": "story", "state": "complete" }],
      "onFailure": { "workType": "story", "state": "failed" },
      "resources": [{ "name": "agent-slot", "capacity": 1 }]
    }
  ]
}

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.
TypeWhat it boundsMetadata you need
MODELLocal managed model assets and loaded-handle capacityRequires model (managed runtime identity), backend, and loadPolicy
PROVIDER_QUOTAProvider-wide cloud quota or request budgetRequires provider and model
INVOCATION_SLOTPer-model or per-provider concurrencyCarry 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.

Limits And Assumptions

Resources coverage is bounded-concurrency pools, requirements, ownership, a minimal capacity example, and a typed-resource overview. It is not a sync of packaged CLI docs, not the configuration topology overview, not worker backends, not workstation routing or lifecycle, and not portability supportingFiles. Sibling configuration, workers, and workstations pages aid discovery; they are not required to define what a resource pool is.

Tags