Codecs
A codec pairs JSON encode and decode functions. Decode errors carry a reason and field path. The null codec represents the canonical no-argument query document.
pub type Codec(a) {
Codec(encode: fn(a) -> String, decode: fn(String) -> Result(a, DecodeError))
}
pub type DecodeError {
DecodeError(reason: String, path: List(String))
}
pub fn json_codec(
encoder: fn(a) -> json.Json,
decoder: decode.Decoder(a),
) -> Codec(a)
pub fn null_codec() -> Codec(Nil)
Signals and queries
Signal references bind a name to a payload codec. Receive waits durably; send delivers to a workflow id. Register a query handler before the first yield point that should answer it. Query callbacks return a value and must remain read-only.
pub opaque type SignalRef(payload)
pub fn new(name: String, payload_codec: Codec(payload)) -> SignalRef(payload)
pub fn name(reference: SignalRef(payload)) -> String
pub fn codec(reference: SignalRef(payload)) -> Codec(payload)
pub fn receive(
reference: SignalRef(payload),
) -> Result(payload, error.ReceiveError)
pub fn send(
workflow_id: String,
reference: SignalRef(payload),
payload: payload,
) -> Result(Nil, error.EngineError)
pub fn handler(
name: String,
arguments_codec: Codec(arguments),
value_codec: Codec(value),
reply: fn(arguments) -> value,
) -> Result(Nil, error.QueryError)
pub fn dispatch(
name: String,
arguments_codec: Codec(arguments),
arguments: arguments,
value_codec: Codec(value),
) -> Result(value, error.QueryError)
Children and durations
A child handle carries its result codecs. Await decodes success or the typed child error. Duration constructors convert explicit units to the SDK’s millisecond representation.
pub opaque type ChildHandle(output, workflow_error)
pub fn spawn(
name: String,
workflow_fn: fn(input) -> Result(output, workflow_error),
input: input,
input_codec: Codec(input),
output_codec: Codec(output),
error_codec: Codec(workflow_error),
) -> Result(ChildHandle(output, workflow_error), error.EngineError)
pub fn await(
handle: ChildHandle(output, workflow_error),
) -> Result(output, error.ChildError(workflow_error))
pub fn spawn_and_wait(
name: String,
workflow_fn: fn(input) -> Result(output, workflow_error),
input: input,
input_codec: Codec(input),
output_codec: Codec(output),
error_codec: Codec(workflow_error),
) -> Result(output, error.ChildError(workflow_error))
pub fn child_id(handle: ChildHandle(output, workflow_error)) -> String
pub fn output_codec(
handle: ChildHandle(output, workflow_error),
) -> Codec(output)
pub fn error_codec(
handle: ChildHandle(output, workflow_error),
) -> Codec(workflow_error)
pub opaque type Duration
pub fn milliseconds(value: Int) -> Duration
pub fn seconds(value: Int) -> Duration
pub fn minutes(value: Int) -> Duration
pub fn hours(value: Int) -> Duration
pub fn days(value: Int) -> Duration
pub fn to_milliseconds(duration: Duration) -> Int
Agent outcomes and errors
Agent outcomes carry the harness’s text, final message, stop reason and session id. Typed errors distinguish activity, timeout, cancellation, replay mismatch, decoding, query and child failures.
pub type AgentOutcome {
AgentOutcome(text: String, final_message: String, stop_reason: String, session_id: String)
}
pub fn outcome_codec() -> Codec(AgentOutcome)
pub type ActivityError {
Retryable(message: String, details: String)
PolicyRefused(message: String)
Terminal(message: String, details: String)
ActivityDecodeFailed(codec.DecodeError)
ActivityTimedOut(TimeoutError)
ActivityCancelled(CancellationError)
ActivityNonDeterministic(NonDeterminismError)
ActivityEngineFailure(message: String)
}
pub type TimeoutError {
TimedOut(message: String)
}
pub type CancellationError {
Cancelled(reason: String)
}
pub type NonDeterminismError {
NonDeterminismViolation(message: String)
}
pub type EngineError {
EngineFailure(message: String)
}
pub type WorkflowError {
WorkflowEngineFailure(message: String)
}
pub type BoundaryDecodeError {
DecodeFailed(codec.DecodeError)
}
pub type ReceiveError {
ReceiveDecodeFailed(codec.DecodeError)
UnknownSignal(name: String)
ReceiveCancelled(CancellationError)
ReceiveNonDeterministic(NonDeterminismError)
ReceiveEngineFailure(message: String)
}
pub type QueryError {
QueryDecodeFailed(codec.DecodeError)
UnknownQuery(name: String)
QueryTimedOut(TimeoutError)
QueryNotRunning(workflow_id: String)
QueryHandlerFailed(message: String)
QueryEngineFailure(message: String)
}
pub type ChildError(workflow_error) {
ChildWorkflowFailed(workflow_error)
ChildCancelled(reason: String)
ChildTimedOut(timeout: String)
ChildOutputDecodeFailed(codec.DecodeError)
ChildErrorDecodeFailed(codec.DecodeError)
ChildEngineFailure(message: String)
}
pub type TimeoutResultError(error) {
TimedOutError(TimeoutError)
InnerError(error)
TimeoutEngineFailure(message: String)
}
pub fn retryable(message: String) -> ActivityError
pub fn retryable_with_details(
message: String,
details: String,
) -> ActivityError
pub fn policy_refused(message: String) -> ActivityError
pub fn terminal(message: String) -> ActivityError
pub fn terminal_with_details(
message: String,
details: String,
) -> ActivityError
Manifests and tests
Manifest encoding serializes the supplied activity declarations. Testing creates an isolated deterministic environment with virtual time, mocked activities and children, recorded observations and replay assertions.
pub fn to_json(declarations: List(Declaration)) -> String
pub opaque type TestEnv
pub fn new() -> Result(TestEnv, error.EngineError)
pub fn process_key(env: TestEnv) -> String
pub fn run(workflow: fn(TestEnv) -> value) -> Result(value, error.EngineError)
pub fn advance(
env: TestEnv,
by: duration.Duration,
) -> Result(TestEnv, error.EngineError)
pub fn current_time_milliseconds(
env: TestEnv,
) -> Result(Int, error.EngineError)
pub fn mock_activity(
env: TestEnv,
activity_value: Activity(input, output),
handler: fn(input) -> Result(output, error.ActivityError),
) -> Result(TestEnv, error.EngineError)
pub fn mock_child(
env: TestEnv,
name: String,
input_codec: Codec(input),
output_codec: Codec(output),
error_codec: Codec(workflow_error),
handler: fn(input) -> Result(output, workflow_error),
) -> Result(TestEnv, error.EngineError)
pub fn observations(_env: TestEnv) -> Result(String, error.EngineError)
pub fn recorded_observations(_env: TestEnv) -> Result(Int, error.EngineError)
pub fn clear_observations(env: TestEnv) -> Result(TestEnv, error.EngineError)
pub fn assert_replay(
env: TestEnv,
workflow: fn() -> Result(value, workflow_error),
) -> Result(value, replay.ReplayError(workflow_error))
These modules live under gleam/aion_flow/src/aion. The test helpers use the engine’s linked testing functions; run them in the Aion test environment.
On main, gleam/aion_flow/src/aion/signal.gleam:1–102, query.gleam:1–137 and child.gleam:1–204 declare the signal, query and child APIs. The remaining modules named above define their own public types and functions.