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-engineas 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 stateWorkflowCheckpointStore— store revisioned checkpointsWorkflowPersistence<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
| Aspect | Status |
|---|---|
| Shipped | Yes |
| Tested | Yes |
| Optional | Yes |
| Experimental | Yes |
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
- Orchestration Persistence — state codecs, checkpoint stores, leases
- Scheduling — cron-triggered workflow execution
- Workflow Server — expose workflows over HTTP
