Turns
A Turn is one input admitted to a Session. It has
its own ID and a sequence number within the Session. Only one Turn runs at a
time in a Session, and Helmr calls the Agent’s turn handler once for each
Turn.
Status
| Status | Meaning |
|---|---|
queued |
Admitted and waiting to run. |
running |
The turn handler is processing. |
completed |
The handler succeeded; its result and optional response are committed. Disk saving continues in the background. |
failed |
The handler threw, returned an invalid result or broke the Turn contract. |
interrupted |
An interrupt, maxTurnDuration, or process or host loss stopped the Turn before it completed. |
cancelled |
Cancelling the Session cancelled this Turn. |
completed, failed, interrupted and cancelled are terminal.
Output, response and result
A Turn produces three separate things:
| Written with | Purpose | |
|---|---|---|
| Output | turn.output.write(value), turn.output.pipe(values) |
Human-facing progress, readable while the Turn runs. |
| Response | turn.respond(value) |
An optional human-facing answer, delivered with a successful outcome. |
| Result | The handler’s return value | A JSON machine result for the caller. |
async turn(turn) {
await turn.output.write("Checking the build")
await turn.respond("The build is green.")
return { status: "green" }
}
Output can be read as soon as it is written, before the Turn finishes. A
handler’s return, the harness’s final text or the end of output does not by
itself mean the Turn is completed.
Finalization
When the handler returns, the Turn stops accepting new messages and questions.
Helmr waits for already admitted output writes, callbacks, questions and native
work to settle. It then commits the result, optional response and completed
outcome together, and requests a background disk save. The next Turn can run
while that save is pending.
Finish your own writes and flush buffers before returning. A completed result does not prove those files have reached remote storage. Helmr retries failed saves without rerunning completed handlers. If the worker is lost first, the response remains available, but files and native conversation history after the restored save can be missing. See Durability.
Observing the outcome
Wait for a Turn with turn.wait() or helmr session turn wait, or read it with
turn.get() or helmr session turn get. The outcome includes the status, the
result, the response and an error code for failures. A wait with a timeout can
return timeout; that ends the wait only, not the Turn. Use
Turn interrupt to stop only the running Turn,
or Session interrupt to also hold queued work.
Stored inputs, results and responses are kept for the Environment’s history retention period. After that, reads report that the payload has expired while the Turn’s identity and status remain.
After a failure
A failed Turn normally leaves the Session open, and the next queued Turn
runs. If the harness’s work cannot be stopped cleanly after the failure, that
counts as a process failure and the next Turn runs on a new process.
An exact-Turn interrupt lets the next queued Turn run once processing has
stopped. A Turn that exceeds maxTurnDuration ends interrupted, its process
stops, and the next queued Turn runs on a new process. When the process fails,
the next queued Turn also runs on a new process; three consecutive process
failures hold the Session until someone resumes it. Session interruption holds
the Session too. Worker loss restores eligible saved files;
missing completed work requires the recovery acknowledgement described in
Durability. Helmr never replays a
completed, interrupted or failed Turn. Retrying business work and reconciling
external effects belong to the application.