threadId.
Pending interactions block new user input. Harnest validates the authenticated user, thread ownership, expiry, and one-time delivery before resuming. Repeated or unmatched submissions are rejected without repeating the action.
Human approval
When an agent requests approval, Harnest emits state and message snapshots, thenRUN_FINISHED with an interrupt outcome. Show the decision in your UI and send a response for every open interrupt:
Argument edits are not accepted. Changed arguments require a new approval. See Human approvals for requesting a decision from agent code.
Browser tools
Declare a capability with@client_tool in your Harnest agent and register its handler in the frontend. Harnest emits the tool call and finishes the transport run without an interrupt outcome, allowing the frontend handler to execute automatically.
Append a standard AG-UI tool message to the current history and send it in a new run on the same thread. The appended message has this shape:
content must be a string. Harnest decodes JSON strings before validating the tool’s output contract and resuming the original invocation. Keep the current message history and state in the request so snapshots retain the conversation.
The optional CUSTOM event named harnest.client_tool also supplies a request ID. Custom clients can submit that ID as resume[].interruptId, with status: "resolved" and the tool output in payload.
Private client input
@client_input ends the run with an interrupt whose reason is private_input. Its responseSchema describes the private form, and metadata.harnest.privateInput is true.
Render a private form and submit its value only in resume[].payload:
messages and state from this resume. Harnest rejects private resumes containing either non-empty field, because transcript messages and state can be echoed in AG-UI snapshots. Do not append the value as a tool message or register this interaction as an automatic frontend tool result. Clear the form value after submission and exclude it from client logging and analytics.
Harnest delivers the value once to the trusted application handler. The handler must return None; only its separately declared response can become a model tool result. Cancellation uses status: "cancelled" without a payload. If the serving process restarts, begin a new interaction instead of replaying private input.
External waits
An external wait emitsCUSTOM named harnest.external_wait, then ends the transport run with result.status: "in_progress". Poll the supplied response ID using the same session and authenticated user: