Attributes
Attributes connect Steps and control how input values are selected.
Values Shared by Steps
An Attribute is a named value in Flow state. A Step consumes Attributes as inputs and contributes new values as outputs. Matching names create the dependency between a producer and every consumer that needs its value.
- Inputs are the values a Step consumes.
- Outputs are the values it contributes to the Flow.
Attribute Roles
Each Attribute has a role that defines how it’s used:
Required Input
The Step cannot execute until this value is available. Required inputs must come from the Flow’s initial state or from upstream Steps: earlier Steps that produce values used by it.
Optional Input
The Step can execute without this value. Optional inputs can have a default value and a deadline (milliseconds) after which the Step proceeds with whatever is available.
Constant
A fixed value built into the Step definition, sent as input on every execution. Useful for configuration that belongs to the Step rather than the Flow:
{
"region": {
"role": "const",
"type": "string",
"const": { "value": "\"us-east-1\"" }
}
}
Metadata
A value drawn from execution metadata at invocation time. The key selects a field such as flow_id, step_id, receipt_token, or webhook_url. Argyll resolves it separately for each Work Item and sends it as a Step-local input:
{
"callback_url": {
"role": "meta",
"meta": { "key": "webhook_url" }
}
}
Output
The Step produces this Attribute value. Outputs become available to downstream Steps: later Steps that declare them as inputs.
Attribute Types
Attributes can be any JSON type:
- Strings
- Numbers
- Objects
- Arrays
- Booleans
- Null
Invocation Mapping
The name used in Flow state is the Attribute’s outer name: the key in the Step’s attributes object. A mapping.name gives that Attribute a different inner name in the HTTP request or response.
This Step consumes the Flow Attribute customer_id but sends it to the endpoint as customerId:
{
"customer_id": {
"role": "required",
"type": "string",
"required": {
"mapping": { "name": "customerId" }
}
}
}
Input mapping changes the name and optional value transformation before invocation. Output mapping reads the endpoint’s inner name or transforms its response, then stores the result under the outer Attribute name for downstream Steps. A mapping.script supplies a Lua or JPath transformation when renaming alone is not enough.
Collection Policies
When multiple Steps can produce the same Attribute, the Collection Policy on an input controls when the Step is satisfied and what value it receives. Set it inside the input’s role-specific configuration:
{
"price": {
"role": "required",
"type": "number",
"required": { "collect": "last" }
}
}
| Policy | Satisfied when | Value received |
|---|---|---|
first | First value arrives | That value (remaining providers removed because they are no longer needed) |
last | All providers finish | The last value produced |
some | All providers finish | Array of all values that arrived |
all | All providers finish, all succeeded | Array of all values |
none | All providers finish with no value | Nothing (gating on absence) |
The default policy is first.
receives 12"| Done["Executes"] style Done fill:#e8f5e9
none behaves differently from the other policies: it satisfies the input when upstream Steps produce nothing. Use it to run a Step only after confirming that a value is absent; for example, proceed only if no fraud signal was raised.
Collection Deadline
Optional inputs can declare a deadline (milliseconds). The deadline starts when the Step’s required inputs are satisfied. When it expires, the Step takes the best available value according to its collect policy, or falls back to the declared default. Later upstream values still flow to other consumers, but this Step won’t restart to use them.
{
"profile": {
"role": "optional",
"type": "object",
"optional": {
"collect": "last",
"deadline": 2000,
"default": "{}"
}
}
}
If all upstream providers complete before the deadline without satisfying the input, the Step resolves immediately rather than waiting for the deadline to expire. There is nothing left to wait for.