Sessions and decisions
A session is the durable conversation of one workflow: one transcript, one set of variables, one folder of files and one position in the machine. A turn is one invocation on it: a start, a chat message, a firing. Sessions are what the platform records, lists and lets you act on, whichever way they began.
Sessions and turns
Section titled “Sessions and turns”A session is of one of three kinds: workflow, chat (a chat conversation, one session however
many messages it holds) or design (a thread of the design agent).
Each arrival extends its session rather than restarting it. A session’s first turn begins at
the start state of the trigger that opened it; every later turn begins where the previous one
left the session, terminal state included, with the transcript, the variables and the files still
there. To get out of a terminal state the agent calls archmax_reset.
A turn moves through these statuses, and its session shows its newest turn’s:
| Status | Shown as | Meaning |
|---|---|---|
queued |
Queued | waiting for a dispatcher |
running |
Running | the agent is working |
awaiting_decision |
Awaiting decision | parked at a human state |
awaiting_input |
Waiting for event | parked by the agent with archmax_wait |
succeeded |
Succeeded | finished |
failed |
Failed | finished with an error |
cancelled |
Stopped | stopped by a member |
A finished turn does not finish the conversation: the next arrival takes a new turn on it. A parked turn is resumed in place, so a decision or a delivered firing continues the same turn rather than adding one.
A turn executes in a worker: a process of its own that holds none of the platform’s secrets. The agent, its tools, its scripts and its child sessions all execute there. The worker reaches only the session’s folders and saved state, the authored tree the turn executes, the folders and remote mounts the workflow grants, and the credentials of the connections its states use, and only through the platform. Nothing of the turn executes in the platform’s dispatcher. A resumed turn continues in a new worker, from the session’s saved state. A worker that fails fails its turn, with a message naming why, and the dispatcher goes on serving other turns. It can fail by running out of memory, by losing its connection to the platform, or by working longer than the deployment allows without parking (an hour unless the operator changed it). An evaluation case executes in a worker of its own in the same way.
Every session also records its origin, decided by how it opened. Sessions started from the editor or the Sessions page, firings a listen window observes, replays and evaluation cases are testing and execute the draft; deployed triggers’ firings, MCP endpoint calls and chats started on the Chat page are production and execute the published version they opened on (see Agents and environments).
Which session an arrival joins
Section titled “Which session an arrival joins”An arrival that names its session (a chat message, a start from a selected session) goes to it.
Otherwise a trigger may declare a session path, a dotted path over the firing’s variables such
as triggers.-1.conversationId; firings that resolve the same value continue the same session (see
Triggers). With neither, every firing opens its own session. The session’s
newest turn then decides what happens:
| Newest turn | What the arrival does |
|---|---|
| none, or finished | takes a new turn, continuing from the session’s position |
| parked awaiting input | is delivered into the parked turn |
| parked awaiting a decision | waits: only a decision resumes it |
| queued or running | waits: a session has one writer at a time |
A trigger’s firing that has to wait is retried for a bounded time and then recorded as undelivered with the reason. A person’s own arrival, such as a start or a chat message, is refused instead, naming what the turn is doing.
The Sessions page
Section titled “The Sessions page”Sessions in the rail is the page an environment opens on until you have had another rail entry
open, and it is headed with the agent’s name. It shows every session you may see: those that
belong to no member (trigger firings, endpoint callers, manual starts, evaluation cases) and your
own chats, which carry a lock because they are personal. Another member’s chats are not listed,
except to the agent’s Administrators (sessions:personal).
What you may do here follows your role on the agent (see Roles and groups): a Reader reads sessions, turns and decisions; a User also starts sessions, decides, replies, cancels and tags; deleting a session needs the agent’s Administrator.
The board, the default view, has four columns in the order a session moves through them:
| Column | Holds |
|---|---|
| Planned | queued sessions, sessions waiting for an outside firing, and upcoming scheduled firings |
| Running | sessions whose turn is running |
| Needs you | sessions parked at a human state |
| Finished | succeeded, failed and stopped sessions |
A bar above each column shows its share of the board. A card is named by the title the agent gave
the session (the title variable), or by the workflow’s title; its foot line carries the status
mark, the state it is in and how long ago it last moved. A card waiting for a firing that named a
resume time shows it. Each column shows eight cards and offers more; Finished hands off to the
table. Cards cannot be dragged: a session’s column is what the runtime reports, not something you
assign.
The table lists status, workflow, trigger, latest message, turns and last activity, with tags beside the workflow’s name. Both views share one filter row: workflow, origin, tags, and a Last activity range (Today, Last 7, 14, 30 or 90 days, All time, or a custom range), which opens on the last 14 days. The table adds a status filter. The selection is remembered per environment; the search term is not.
The table’s filter row ends with Columns. It lists the session attributes the environment’s workflows have written, each with the workflows that wrote it, and narrows to one workflow while the workflow filter is set. Each attribute you tick becomes a column after Turns, up to eight. A number reads in your locale, a boolean reads Yes or No, and a session without the attribute shows a dash. The columns are remembered per environment in your browser. They are not filters: they never hide a row, and Clear filters leaves them alone.
Start session in the header starts a workflow by hand: pick a workflow whose definition
declares a manual entry and fill in the variables it requires. For a File input you choose a
file to upload; it is placed in the new session’s attachments/. Right-clicking a row, a card or a
session in the session view’s list offers Delete session.
The session view
Section titled “The session view”Opening a session lands on its newest turn in the workflow’s session view (your own production
chat opens on the Chat page instead): the workflow’s graph, read-only, with the sessions listed
beside it and a detail panel. The graph draws the selected turn’s path. The state it is in has a
border in the success colour that travels around the card, states it left keep a still border in
that colour, and the state a failed turn stopped in is bordered in the error colour (see
brand colours). When the agent called archmax_reset, the path
starts over at the state it reset to. States an earlier turn of the session entered, and states
this turn left by resetting, are drawn between those and the untouched ones. When the turn executed an older definition than the
current one, a clock icon in the mode bubble says so, and the graph shows the definition it
executed.
Summary in the mode bubble opens the panel on the session: its Session ID, its turns newest first (select one to read it), when and by which trigger the turn was resumed, the turn’s prompt, outcome, timings, tokens and spend, its tags (added and removed here), its session attributes (read-only), the session it is About when a completion trigger opened it, a Variables tree marking what was given to the turn and what the agent set, and the session’s Files. Clicking a state card shows what happened in it instead, visit by visit: the agent’s messages, its tool calls with their arguments and results, hook verdicts and token usage. A live turn streams into the view as it happens.
While the session’s turn is live, Stop in the mode bubble cancels it.
Session attributes
Section titled “Session attributes”A session attribute is a key-value pair an agent records on a session: a rating, a category, a resolved flag.
- Keys. A key starts with a lowercase letter, followed by lowercase letters, digits,
_or-, at most 64 characters. - Values. A value is text (at most 1,000 characters), a number or a boolean. Its kind is the
value’s own and is never declared:
4is a number,"4"is text, and0.82is a decimal. - Limit. A session carries at most 32 attributes.
- What they are not. The harness never reads attributes, and they are not variables. Members cannot edit them: tags stay the member’s labels.
A state records attributes with the Sessions tool sessions__set_attributes, which you grant
in tools.allow like any tool. It writes keys onto a session and keeps every key it does not
name; null removes a key. Its session argument is the id of the session to write:
- omitted, the session the turn runs in, whose id every turn holds in the locked
sessionvariable (${{session}}); - or the subject session,
${{triggers.-1.session}}.
Any other id is refused. A child session writes its root session’s attributes.
Bind the argument with a guard so the agent cannot pick the wrong session. In the editor, the
tool’s card shows a session guard row from the start, with ${{triggers.-1.session}} as its
placeholder; focusing it offers that and ${{session}}.
The session variable
Section titled “The session variable”Every turn holds its own session’s id in the variable session. The platform seeds it beside
triggers, it is locked so no state can overwrite it, and a start’s own variables cannot
displace it. Read it with archmax_get_variables({ name: "session" }), or write ${{session}}
in a guard or a tool argument. A child session is seeded by its call and holds no session of
its own.
Sessions about another session
Section titled “Sessions about another session”A completion trigger opens a session about one finished session of another workflow, its subject session. That session:
- reads its subject with
sessions__read_subject. The result holds the subject’s summary and its turns, oldest first, with their messages. A tool call is named without its arguments, a tool result is cut after 2,000 characters, and a long conversation keeps its newest 60,000 characters, saying how many older messages it left out; - writes its subject’s attributes with
sessions__set_attributes, passingsession: "${{triggers.-1.session}}"; - reaches nothing else. The tools take no session id, so a session reaches only itself and its own subject;
- belongs to the member the subject belongs to, so what it reads of a personal chat stays as private as the chat;
- fires no completion trigger of its own.
Human states and decisions
Section titled “Human states and decisions”When a turn reaches a state of type: human, it parks and records a
decision: the state, its declared transitions, its
evidence files, its approvers and the agent’s handoff message. The session appears under
Needs you, marked when it is a testing session.
Activating the card opens the decision dialog. It shows the approvers, the evidence (Markdown rendered, HTML in a sandbox, other text as text), a Note to agent and one row per declared transition, each naming the state it leads to. A decision a child session raised names both workflows, reads its evidence from that child session’s own files, and its Details open the child session in the session view. No transition is the default. To take one, hold its button:
- keep the pointer, or Enter or Space, down on the button for three seconds; a bar fills it from left to right and the decision is submitted when it is full;
- a click, a tap or any shorter press submits nothing, and neither does releasing early, moving off the button or losing focus;
- the button’s tooltip names the transition and says to press and hold for 3 seconds to confirm.
The chosen transition and the note resume the parked turn, and the dialog moves on to the next decision in the column, with previous and next controls to step through them. A decided decision shows its outcome, its note, who decided and when, and nothing to change. Details opens the session in its workflow’s session view. A decision can also be resolved by an AG-UI client (see Chat, AG-UI and MCP endpoints).
Parked sessions
Section titled “Parked sessions”An agent parks its session from inside a state by calling archmax_wait with a reason, and
optionally a time to be woken (30m, 2h, 1d or an instant). Nothing is decided by a person:
the next arrival for the session is delivered into the state that parked, which reads what arrived
and chooses its own transition. The platform wakes a park whose time has come by delivering a
timer firing; a real firing that arrives earlier resumes it at once. A park that named no time
waits until something arrives, or until you stop it. See the harness’s
sessions guide.
When a message reaches a parked session, it is appended to the transcript before the turn resumes,
so the agent sees what it is answering. A firing is such a message when its trigger’s message path
resolves one, or, without a path, when its payload carries a top-level message, text or
content. Every firing that reaches a turn is also appended to that turn’s triggers variable,
the newest last as triggers.-1.
Child sessions
Section titled “Child sessions”A state that is allowed another workflow’s archmax_workflow_<slug> tool can call it; the call runs
that workflow as a child session inside the calling turn,
and its result comes back as the tool’s result. The target is entered at its manual entry, so
the call supplies that entry’s requires. Assign targets in the state inspector’s
Sub-workflows section.
A child session has a folder of its own, and every tool it calls works there: the agent’s own
file tools and the platform’s alike, so a file files__unpack_file writes is one read_file
finds. A child session cannot read its caller’s files, and its caller cannot read its files.
Files cross only through the target’s manual entry. A type: file argument is copied into the
child’s scratchpad/attachments/, and a type: file return is copied back into the caller’s,
under a name nothing there holds: a second report.pdf becomes report-1.pdf. To hand over
several files, declare several entries; to hand over a folder, pack it into one file with
files__pack_files first. A file a child session writes and does not return stays in its own
folder.
A child session’s states never appear in the parent’s graph. Its calls are listed in the activity
of the state that made them, each with its workflow, its outcome and how long it took. Opening one
draws the child workflow’s graph with that child session’s own progress, a breadcrumb in the mode
bubble walks back out, and the URL records it as dispatch. A session numbers its dispatches from
1 across all its turns, so dispatch=2 is its second, and dispatch=1~1 is the first one the
child session of dispatch 1 made in turn. The summary of an open child session lists its own
files, not its caller’s, and a file its transcript links opens from its own folder. A child
session started before child sessions were numbered shows no files. A child’s graph is its definition as it stands now,
which the view marks. A human state reached inside a child session parks the whole session; the
decision names both workflows and resumes the child, then the parent. See the harness’s
sub-workflows guide.
Session files
Section titled “Session files”A session has one folder for its whole life, so a file one turn writes is there for the next. The
agent writes its work under scratchpad/; files you attach in a chat, and the binary files tools
return, land under attachments/. A firing’s payload is never written as a file: it is the triggers
variable. The Files section of the summary lists the folder read-only, previews text files up
to their first 256 KB, and downloads any file, binary ones included.
Cancelling and deleting
Section titled “Cancelling and deleting”Stop cancels the session’s current turn, whether queued, running or parked; the turn ends as Stopped, never as failed. It ends the turn, not the conversation: the session keeps its position, transcript and files, and a later firing takes a new turn on it. Stopping is how you end a park that nothing will resume.
A running turn is asked to stop first, so its current model or tool call can end cleanly. One that has not stopped ten seconds later is ended together with its worker, and is recorded as Stopped all the same. What it wrote before it stopped stays written.
Delete session removes a session and all its turns from every listing and from the decisions; a live turn is stopped first. Its files go with it, and so do the files of every child session it started. A later firing for the same session opens a new one. A session cannot be re-pointed at a newer version: to move a production session off a defective version, delete or stop it and let the next firing open a fresh one.