Core Concepts Overview
Understanding Moco's core concepts will help you build powerful and efficient workflows.
Workflowspec
A workflowspec is a YAML document that defines a complete workflow. It specifies:
- Workflow identity (name and version)
- Input parameters
- Initial context variables
- The workflow body (execution logic)
- Output specification
wfspec_name: my-workflow
wfspec_version: 1.0.0
context:
status: pending
input_data:
user_id:
output_name: result
body:
# Workflow logic here
Statements
Statements are the building blocks of workflows. They come in two categories:
Primitive Statements
Leaf nodes that perform specific actions:
- transform: Data transformations and variable assignments
- abort: Workflow termination (abort, terminate, break, raise)
- activity: Execute external functions/services
- workflow: Execute child workflows
- wait_for: Wait for events or timeouts
- emit_event: Send events to the event bus
Composite Statements
Containers that orchestrate other statements:
- sequence: Execute statements sequentially
- parallel: Execute statements concurrently
- iteration: Loop over collections
- state_machine: Event-driven finite state machines
Expressions
Expressions provide dynamic behavior using Python syntax:
# Simple expression
total: "{{ price * quantity }}"
# Complex expression with list comprehension
result: "{{ sum([item['price'] for item in items]) }}"
# Conditional expression
discount: "{{ price * 0.1 if price > 100 else 0 }}"
Expression Types
- python: Standard Python evaluation (default)
- python_glom: Path-based data extraction
- literal: No evaluation, treat as string
- jinja: Jinja2 template rendering
Activities
Activities are external functions or services that workflows can invoke:
- activity:
type: builtin.http_request
input_data:
method: GET
url: https://api.example.com/data
timeout_sec: 30
max_retry_attempts: 3
output_name: api_result
Built-in activities include:
- HTTP requests
- Delays
- Event emission
- State persistence
- Secret management
- Workflow execution
Custom activities can be registered via activity providers.
Context and Variables
Workflows maintain a context (variable store) throughout execution:
- Context: Initial variables defined in the workflowspec
- Input Data: Parameters passed when starting the workflow
- Output Data: Values computed during execution
- Special Variables:
_: Root context (all variables)__user_info__: User information__sys_info__: System info (workflow_id, trace_id, etc.)iter_item: Current item in iterationiter_items: All items in iteration
Variable Modifiers
Control how variables are evaluated and stored:
# Container scope (temporary, not persisted)
temp@: "{{ calculation() }}"
# Debug logging
value#: "{{ important_data }}"
# Force expression type
template#literal: "{{ not_evaluated }}"
path#python_glom: "data.nested.field"
Runtime Modes
Moco supports two runtime modes:
In-Memory Runtime
- Fast, synchronous execution
- Perfect for development and testing
- No external dependencies
- Limited to single-process execution
Temporal.io Runtime
- Production-grade distributed execution
- Durable workflow state
- Automatic retries and timeouts
- Horizontal scaling
- Workflow history and replay
- Activity isolation
Switch between modes using environment variables - no code changes needed!
Events
Workflows can communicate via events:
Emitting Events
- emit_event:
input_data:
topic: notifications
data:
message: "Task complete"
result: "{{ result }}"
Waiting for Events
- wait_for:
event:
topic: notifications
match_expression: "{{ event.data.get('id') == task_id }}"
timeout_sec: 60
output_name: received_event
Events enable:
- Parent-child workflow communication
- Multi-agent coordination
- State machine transitions
- Asynchronous notifications
Child Workflows
Workflows can execute other workflows with different execution modes:
- nested: Child shares parent's context
- sync: Child runs independently, parent waits for result
- async: Child runs independently, parent waits for start
- detached: Child runs completely independently
- workflow:
wfspec:
name: child-workflow
version: 1.0.0
child_mode: sync
input_data:
param: "{{ value }}"
output_name: child_result
State Machines
For complex event-driven workflows, use state machines:
state_machine:
name: order-fsm
initial_state: pending
states:
- name: pending
- name: processing
- name: completed
is_terminal: true
transitions:
- from_state: pending
to_state: processing
trigger:
event_name: start
State machines provide:
- Explicit state management
- Event-driven transitions
- State-specific timeouts
- Entry/exit callbacks
- Global transitions
Next Steps
Dive deeper into specific topics: