Skip to content
archmax.ai

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.

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).

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.

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.

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.

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: 4 is a number, "4" is text, and 0.82 is 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 session variable (${{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}}.

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.

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, passing session: "${{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.

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).

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.

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.

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.

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.