Skip to main content

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 iteration
    • iter_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: