Debug, audit, and replay
Read OrchaJS JSONL session events with .events() for debugging, audit, and replay.
Use .events() when you need the exact durable record for auditing,
debugging, or replay:
const page = await orcha.supportAgent.events(sessionId, {
page: 1,
pageSize: 100,
});
for (const event of page.events) {
console.log(event.sequence, event.type, event.data);
}These are the pure events stored by the default Node runtime at:
.orcha/sessions/<agentName>/<sessionId>.jsonlThis append-only event stream is not just a debug log. Orcha derives the agent's functioning session state, history, pending client actions, usage, and resumable context from it.
Use .history() for normal conversation UI. Use .events() when the exact
internal timeline matters.
Example response
{
events: [
{
sequence: 1, // Position in this session.
type: "session.created", // What happened.
timestamp: "2026-09-28T12:00:00Z", // ISO timestamp.
data: {
schemaVersion: 1,
sessionId: "ses_01K...",
agent: "supportAgent",
status: "active",
metadata: {},
variables: {},
},
},
{
sequence: 2,
type: "run.started",
timestamp: "2026-09-28T12:00:01Z",
run: 1, // Numbered run in the session.
data: {
status: "running",
agent: "supportAgent",
provider: "anthropic",
model: "claude-sonnet-4-6",
region: "global",
outputType: "text",
clientCapabilities: [],
},
},
],
throughSequence: 12, // Stable upper boundary for pagination.
page: 1,
pageSize: 100,
total: 12,
hasMore: false,
// The current SessionSnapshot is included too.
sessionId: "ses_01K...",
agent: "supportAgent",
status: "active",
metadata: {},
createdAt: "2026-09-28T12:00:00Z",
updatedAt: "2026-09-28T12:00:08Z",
runStatus: "completed",
pendingClientActions: [],
}Paginate against a stable session
Sessions can receive new events while you read older pages. Keep the
throughSequence returned by the first request and send it with later pages:
const latest = await orcha.supportAgent.events(sessionId, {
page: 1,
pageSize: 100,
});
const older = await orcha.supportAgent.events(sessionId, {
page: 2,
pageSize: 100,
throughSequence: latest.throughSequence,
});This keeps every page within the same event boundary. Page 1 is the newest page; higher page numbers move backward.
Most product interfaces should use history()
instead. Do not read .orcha storage files directly.
API reference
events(
sessionId: string,
options?: {
page?: number;
pageSize?: number;
throughSequence?: number;
},
): Promise<SessionEvents>
type SessionEvents = SessionSnapshot & {
events: SessionEvent[];
throughSequence: number;
page: number;
pageSize: number;
total: number;
hasMore: boolean;
};pagedefaults to1.pageSizedefaults to50and accepts1through100.throughSequencefixes the newest event included across paginated calls.totalcounts events inside that sequence boundary.- Snapshot fields describe the current session.
Event envelope
type SessionEvent = {
sequence: number;
type: SessionEventType;
timestamp: string;
run?: number;
data: Record<string, unknown>;
};sequenceis unique and strictly ordered within one session.typeidentifies the event and the shape ofdata.timestampis an ISO timestamp.runidentifies the numbered run. Session-level events omit it.datais the typed payload for that event.
Event types
Session lifecycle:
"session.created"
"session.updated"
"session.paused"
"session.resumed"Run lifecycle:
"run.started"
"run.paused"
"run.completed"
"run.failed"Messages and actions:
"message.created"
"action.requested"
"action.completed"
"action.failed"
"client_action.requested"
"client_action.resolved"Skills, evaluations, and subagents:
"skill.requested"
"skill.loaded"
"skill.failed"
"evaluation.requested"
"evaluation.completed"
"evaluation.failed"
"subagent.initiated"
"subagent.resumed"
"subagent.completed"
"subagent.paused"
"subagent.failed"Tests can additionally write test.warning and test.completed.
Important payloads
// message.created
{
role: "user" | "assistant" | "tool";
content: MessageContent[] | ToolResult[];
// Assistant messages can also include provider, model, usage,
// durationMs, stopReason, responseId, status, and parsedOutput.
}
// client_action.requested
{
status: "waiting";
calls: Array<{
callId: string;
name: string;
arguments: Record<string, unknown>;
}>;
localResults: ToolResult[];
toolCallOrder: string[];
}
// client_action.resolved
{
status: "completed";
results: ToolResult[];
}
// run.paused
{
status: "waiting_for_client_action" | "paused";
clientToolCalls?: ClientToolCall[];
output?: AgentOutput;
usage?: Usage;
durationMs?: number;
}
// run.failed
{
status: "failed";
durationMs: number;
usage?: Usage;
error: {
code: string;
message: string;
retryable?: boolean;
};
}Treat the event log as append-only. Consume events by sequence; never edit
or infer storage filenames.