Processes

The Vertesia Process Engine runs business processes that are a hybrid of deterministic state machines and agentic reasoning. A process defines a graph of nodes connected by transitions, walked by a Temporal workflow. Some nodes are pure code (conditions, tool calls), some call an interaction, some delegate to an autonomous agent, and some pause for a human to review.

The engine is the answer when a plain conversational agent is too loose and a plain DSL workflow is too rigid. You get deterministic routing, durable state, and human-in-the-loop gates — plus agents that can do open-ended sub-tasks bounded by a schema.

When to use a process vs a workflow or an agent

You want…Use
A single agent chatting and calling toolsAgent
Deterministic pipelines authored in JSON DSL or TypeScriptWorkflows
A multi-step business process with branching, gates, retries, and mixed automation + humansProcesses (this section)

A process is well-suited when you can describe the flow as "first do X, then either Y or Z depending on the result, then a human reviews, then finalize."

One authoring distinction matters in the BPMN-aligned native model:

  • condition means choose one path
  • branch means run a fixed set of named branches and join
  • foreach means repeat one child body over a collection

For foreach and branch, the nested child body is task-like leaf work only: use tool, interaction, agent, or process, and keep routing on the parent node.

Persisted native definitions also carry format_version: 1 explicitly so future migrations have a stable schema boundary.

Core concepts

Process definition

A JSON document that the author commits. Key fields:

  • process — stable identifier (e.g. contract_review).
  • initial — the first node id to enter.
  • context.schema — a JSON Schema describing every field the process may read or write. Acts as the typed state the process accumulates.
  • context.initial — starting values for that context.
  • nodes — a map of nodeId → NodeDefinition, each with a type and optional transitions.

Context

Every running process carries a context object, typed by context.schema. Any node that writes process state must declare writes — the exact fields it is allowed to update. The engine rejects non-empty context updates when writes is missing and rejects writes outside that list. Context is capped at 64 KB serialized — for large payloads, store artifact URIs.

Transitions

Each node can declare transitions, each with:

  • to — target node id
  • trigger"auto" (engine picks after guards), "agent" (chosen by an agent node's structured output), or "user" (driven by a human signal)
  • guard — optional JSON Logic rule evaluated against context

Condition nodes use branches instead of transitions and route by when rules with a required default: true branch.

Node definition (high level)

{
    "type": "agent",
    "prompt": "Extract the key terms…",
    "tools": ["fetch_document"],
    "writes": ["parties", "term_length", "total_value"],
    "transitions": [
        { "to": "flag_clauses", "trigger": "agent" }
    ],
    "human_description": "Reads the contract and writes the extracted key terms into process context."
}

See Node types for the full reference.

Runtime model

Each process run is a Temporal workflow (ExecuteProcessWorkflow) that:

  1. Loads the resolved definition into the workflow input (processes are versioned; runs execute against the definition they started with).
  2. Walks node by node, checkpointing to MongoDB every step.
  3. For agent and interaction nodes, spawns a child conversation workflow scoped to a per-node workstream — so every node gets its own conversation view, its own tool use, and its own artifact namespace.
  4. Applies writes to context through the validator (schema + writes scope), then picks the next transition.
  5. On a human_task node, creates a task and waits for a signal from the Task Inbox.

Because it's a Temporal workflow, any node failure is durable and retryable; the run can be resumed after restarts.

Structured split/join follows the same Temporal-native pattern: start child branches, wait for all of them, then continue. Collection fanout is the separate "repeat over items" case.

Observability

Each run has a dedicated UI with three tabs:

  • Process — the state chart, per-node inspector (writes, transitions, context diff per entry), timeline, tasks.
  • Conversation — the live streaming conversation for whichever node's child workflow is active, with workstream tabs for each node's agent run.
  • Observability — the generic agent observability view (Temporal history, conversation snapshots, tool metrics) scoped to the process run.

For end users who need to act on a process, the Task Inbox surfaces readable human_task nodes assigned to them, their groups, or available to claim.

Two execution modes

Every run has a run_type:

  • programmatic (default) — the engine walks the definition deterministically. No outer LLM. This is the right choice for the vast majority of production processes.
  • supervised — a top-level ProcessSupervisor conversation watches the run and can request set_context, transition_to, skip_node, retry_node, continue_process, or fail_process commands. The process workflow validates and applies those commands. transition_to must target a declared exit unless an explicit supervisor override policy is set; skip_node requires skippable: true or an explicit skip policy. Worker agents inside nodes remain schema-constrained regardless.

The conceptual picture of why both modes exist and how they relate is in The Process Model.

Next

  • The Process Model — how to think about processes (read this before authoring).
  • Node types — the reference for each type.
  • Agent nodes — how a worker agent is constrained by a result schema and the node's declared tools.

Was this page helpful?