Browse documentation

Run

Approvals and user input

Pause durable agent work for a decision or missing information, then resume safely.

Approvals protect a known action. User input supplies information that the agent cannot safely infer. Both are durable thread records.

A write that requires approval pauses before the trusted host executes it. The client can list pending approvals and approve or reject one request. After approval, completed earlier calls replay from the journal and the approved write receives a stable idempotency key.

for await (const event of thread.stream()) {
  if (event.type === "approval.requested") {
    await thread.approve({ approvalId: event.approvalId });
  }
}

A write that started but has no terminal record becomes outcome_unknown. Flary does not run it again automatically.

Durable agents include request_user_input by default. It is a small built-in tool beside Code Mode and lazy tool search. Application tools stay lazy.

export const agent = app.agent({
  name: "agent",
  tools,
  // Default: true. Set false only for a non-interactive agent.
  askUser: true,
});

The agent can ask a multiple-choice question or omit the choices for a typed answer. Flary stores the request, pauses the active turn, and returns the answer to the same model tool call. The model can then continue the task or ask one new follow-up question. Questions do not have to be planned in advance.

Requested input uses the same restart-safe client pattern:

await thread.sendInput(requestId, {
  environment: "staging",
});

The flary/react package includes FlaryUserInput for choice controls and free-form answers. A custom UI can use the same thread methods and WebSocket events.

Every approval and input request is tenant-scoped, audited, and available after reconnect.