Tramai Logo
Tramai

Orchestration

tramai-orchestration is TramAI's optional workflow layer. It exists for backend workflows that need explicit coordination across multiple AI-backed or deterministic steps without turning TramAI into an agent framework.

The module is shipped and tested, but should be treated as experimental while the API settles.


What This Covers

  • Workflow DSL: aiStep, localStep, gateStep, branchStep, parallelStep
  • Typed workflow state patterns
  • Engine and orchestration boundaries
  • Workflow-level observability
  • Checkpoint and resume basics

When to Use It

Add tramai-orchestration when you need:

  • multi-step workflows: plan -> execute -> review -> finalize
  • conditional routing: route -> specialist -> validate
  • bounded fan-out: candidate generation followed by judging or reduction
  • explicit checkpoint/resume boundaries

Do NOT use it for:

  • autonomous agent swarms
  • hidden memory systems
  • peer-to-peer agent chat
  • replacing tramai-engine as the owner of provider execution, retries, or tool loops

Minimum Setup

Dependency

implementation("dev.tramai:tramai-orchestration:0.3.1")

Opt In

The module is marked experimental. Opt in where you define or consume workflows:

@OptIn(ExperimentalTramAIOrchestration::class)
fun buildWorkflow() {
    // workflow code here
}

Basic Workflow

@OptIn(ExperimentalTramAIOrchestration::class)
fun buildWorkflow(planner: PlannerService, reviewer: ReviewerService) =
    workflow<ReviewState>("review-workflow") {
        aiStep(
            name = "plan",
            input = { state -> state.request },
            invoke = planner::plan,
            merge = { state, plan -> state.copy(plan = plan) },
        )
        localStep(
            name = "prepare",
            transform = { state, _ -> state.copy(prepared = true) },
        )
        aiStep(
            name = "review",
            input = { state -> ReviewInput(state.request, state.plan ?: error("missing plan")) },
            invoke = reviewer::review,
            merge = { state, result -> state.copy(result = result) },
        )
    }.build { state ->
        state.result ?: error("missing result")
    }

The important property is that workflow state stays explicit and typed.


Available Step Shapes

localStep(...)

Deterministic application logic. Transforms state without calling a provider.

localStep("validate") { state, _ ->
    state.copy(validated = validateInput(state.request))
}

aiStep(...)

One typed AI-backed step over extracted state input.

aiStep(
    name = "classify",
    input = { state -> ClassifyInput(state.text) },
    invoke = classifier::classify,
    merge = { state, result -> state.copy(category = result) },
)

gateStep(...)

First-class approval or policy gates. Workflow suspends until gate decision is made.

gateStep(
    name = "approval",
    decide = { state, _ ->
        if (state.approved) GateDecision.allow()
        else GateDecision.reject("approval required")
    },
)

branchStep(...)

Explicit conditional routing.

branchStep("route", branches = {
    branch("high-value") { /* expensive analysis */ }
    branch("standard") { /* simple processing */ }
}, selector = { state ->
    if (state.amount > 10000) "high-value" else "standard"
})

parallelStep(...)

Bounded fan-out/fan-in execution.

parallelStep("analyze-all", branches = {
    branch("fraud") { aiStep(...) }
    branch("compliance") { aiStep(...) }
    branch("scoring") { aiStep(...) }
})

Engine Boundary

tramai-engine owns:

  • provider execution
  • structured parsing and structured retry
  • fallback routing
  • circuit breaking
  • tool calling
  • token budgets
  • caching
  • operation-level observability

tramai-orchestration owns:

  • workflow state
  • step ordering
  • branching and bounded parallelism
  • workflow-level observation
  • checkpoint and resume
  • optional active ownership through leases

That boundary is why orchestration fits TramAI without changing the product into an agent runtime.


Observability

Workflow execution has its own observation seam through WorkflowObserver.

The repository also includes OpenTelemetryWorkflowObserver in tramai-observability so workflow spans can sit above provider-attempt spans.

Observable workflow events:

  • workflow start and completion
  • checkpoint load/save events
  • lease claim/renew/release events
  • step start, completion, and failure

Persistence and Resume

Checkpoints are written at top-level workflow step boundaries. Completed top-level steps can be skipped on resume.

Persistence is storage-agnostic:

  • WorkflowStateCodec<S> — encode/decode typed state
  • WorkflowCheckpointStore — store revisioned checkpoints
  • WorkflowPersistence<S> — wire codec + store into one workflow run

For details on stores, codecs, file backends, JDBC backends, and lease-based ownership, see Orchestration Persistence.


Current Maturity

AspectStatus
ShippedYes
TestedYes
OptionalYes
ExperimentalYes

The orchestration layer is already useful for explicit backend workflows, but it is still the youngest major public surface in the repository.


Limitations

  • checkpoints happen only at top-level workflow step boundaries
  • nested branch internals are not resumed mid-step
  • in-flight parallel work is not resumed mid-branch
  • partially emitted provider streams are not resumed token-by-token
  • no per-step timeout (a hanging step stalls the entire workflow)
  • no per-step retry with backoff

Next Steps