Resume a session
Resume an OrchaJS session with .resume(), including human-in-the-loop client actions.
Use .resume() with a saved sessionId to continue the same conversation:
const result = await orcha.supportAgent.resume(sessionId, {
content: "What should I do next?",
}).result;Orcha loads the durable context automatically. Do not send previous messages again.
Run, resolve a client action, and resume
A client action moves work into your application. The following is the entire flow in one place:
// 1. Start the session.
let result = await orcha.approvalAgent.run({
content: "Approve a $750 laptop.",
clientCapabilities: ["request_human_approval"],
}).result;
// 2. The agent paused and requested work from your client.
if (result.status === "waiting_for_client_action") {
const call = result.clientToolCalls[0];
if (call.name === "request_human_approval") {
// Resolve this in your UI, mobile app, worker, or other client.
const approved = await showApprovalDialog(call.arguments);
// 3. Return the result and continue the same run.
result = await orcha.approvalAgent.resume(result.sessionId, {
toolResults: [
{
callId: call.callId,
output: {
approved,
note: "Decision submitted by the user.",
},
},
],
}).result;
}
}
if (result.status === "completed") {
console.log(result.output);
}Use call.name to identify the requested client action. call.arguments
matches that action's parameters; the returned output must match its
outputSchema.
For example, a location action can return the fields defined by its own schema:
{
callId: call.callId,
output: {
latitude: 28.6139,
longitude: 77.209,
},
}Resolve multiple client actions
Return one result for every requested call in one .resume():
if (result.status === "waiting_for_client_action") {
const toolResults = await Promise.all(
result.clientToolCalls.map(async (call) => {
const output = await handleClientAction(call.name, call.arguments);
return {
callId: call.callId,
output,
};
}),
);
const next = await orcha.supportAgent.resume(result.sessionId, {
toolResults,
}).result;
}Every pending callId must appear exactly once.
When a client action fails
Keep normal results simple. Add isError: true only when your client could not
perform the action:
{
callId: call.callId,
output: {
message: "The user denied location access.",
},
isError: true,
}The agent receives that failure and can decide what to do next.
API reference
Continue the conversation
resume(
sessionId: string,
input?: string | {
content: string | MessageContent | MessageContent[];
clientCapabilities?: Array<string | { name: string }>;
},
): ExecutionsessionId— the existing session to continue.content— the next user message.clientCapabilities— client actions available for this resumed run.- Omitting
inputasks the agent to"Continue.".
A conversational resume starts a new numbered run in the same session.
Resolve pending client actions
resume(
sessionId: string,
input: {
toolResults: Array<{
callId: string;
output: ClientActionOutput;
isError?: boolean;
}>;
},
): ExecutioncallId— copy it unchanged from the requested call.output— data matching that client action'soutputSchema.isError— optional; usetrueonly when the client action failed.
Do not combine content and toolResults. While actions are pending, resolve
them before sending another conversational message.
Requested call
type ClientToolCall = {
callId: string;
name: string;
arguments: Record<string, unknown>;
};callIduniquely pairs the request with its result.nameis the client action name from itsindex.json.argumentsmatches the action'sparametersschema.
Result
.resume() returns the same Execution and RunResult shapes as
run():
completed— readresult.output.waiting_for_client_action— resolve the newclientToolCalls.paused— the session was explicitly paused.failed— inspectresult.error.
Common client-action errors include missing results, an unknown or duplicated
callId, output that does not match the action schema, and trying to send
content while actions remain pending.