Skip to content

Documentation / @agentick/core / Session

Interface: Session<P> ​

Defined in: core/src/app/types.ts:1516

A persistent session for multi-turn conversations.

Session is an EventEmitter that emits StreamEvent during execution. Use session.events() to convert to an AsyncIterable.

Example ​

typescript
const session = app.session();

// Listen to events via EventEmitter
session.on('event', (event) => console.log(event));

// Or convert to AsyncIterable
for await (const event of session.events()) {
  console.log(event);
}

// Run with props, get handle
const handle = await session.render({ query: "Hello!" });
const result = await handle.result;
console.log(result.response);

// Or get result directly via ProcedurePromise chaining
const result2 = await session.render({ query: "Follow up" }).result;

// Queue messages for next tick
await session.queue.exec({ role: "user", content: [...] });

// Interrupt running execution
session.interrupt({ role: "user", content: [...] }, "user_interrupt");

// Clean up when done
await session.close();

Extends ​

  • EventEmitter

Type Parameters ​

P ​

P = { }

Properties ​

children ​

readonly children: readonly Session<{ }>[]

Defined in: core/src/app/types.ts:1547

Active child sessions (currently running spawns).


currentTick ​

readonly currentTick: number

Defined in: core/src/app/types.ts:1524

Current tick number


dispatch ​

dispatch: Procedure<(name, input) => Promise<ContentBlock[]>, true>

Defined in: core/src/app/types.ts:1689

Dispatch a tool by name (or alias) from the user side. Works on any registered tool regardless of audience. Ensures tree is mounted before dispatch. Validates input against the tool's schema before calling the handler.

Known limitation: If called concurrently with render(), ctx.clear() during compilation briefly removes tools. Both operations are client-initiated so this race doesn't occur in single-user practice.


id ​

readonly id: string

Defined in: core/src/app/types.ts:1518

Unique session ID


isAborted ​

readonly isAborted: boolean

Defined in: core/src/app/types.ts:1527

Whether the session has been aborted


isTerminal ​

readonly isTerminal: boolean

Defined in: core/src/app/types.ts:1530

Whether the session is in a terminal state (closed).


metadata ​

readonly metadata: Readonly<Record<string, unknown>>

Defined in: core/src/app/types.ts:1544

Immutable identity labels set at creation time.


parent ​

readonly parent: Session<{ }> | null

Defined in: core/src/app/types.ts:1533

Parent session, or null for root sessions.


parentSessionId ​

readonly parentSessionId: string | null

Defined in: core/src/app/types.ts:1541

Parent session ID as a string. Survives persistence/restore.

  • Ephemeral spawn children have both parent (live ref) and parentSessionId.
  • Persistent children (delegation) have only parentSessionId.

queue ​

queue: Procedure<(message) => Promise<void>, true>

Defined in: core/src/app/types.ts:1572

Queue a message to be included in the next tick.

Queues the message and notifies onMessage hooks if components are mounted. Does NOT trigger execution - use send() if you want to trigger render().

This is a procedure (without execution boundary) so you can use:

  • session.queue.withContext({ userId }).exec(message)
  • session.queue.use(middleware).exec(message)

queuedMessages ​

readonly queuedMessages: readonly Message[]

Defined in: core/src/app/types.ts:1550

Messages queued for the next tick (read-only view)


render ​

render: Procedure<(props, options?) => SessionExecutionHandle, true>

Defined in: core/src/app/types.ts:1614

Run the component with props, execute tick loop.

Returns SessionExecutionHandle (AsyncIterable, not PromiseLike). If already running, returns the existing handle (hot-update support).

Note: If called with no props (or empty props) and no queued messages, returns an empty handle and does not run a tick.

Example ​

typescript
const handle = await session.render(props);
handle.queueMessage({ role: "user", content: [...] });
const result = await handle.result;

schedulerState ​

readonly schedulerState: SchedulerState | null

Defined in: core/src/app/types.ts:1560

Current scheduler state for DevTools.

Returns the scheduler's current state, including status, pending reasons, and reconciliation metrics.

Returns null if the session hasn't been initialized yet.


send ​

send: Procedure<(input) => SessionExecutionHandle, true>

Defined in: core/src/app/types.ts:1596

Send messages and/or update props.

Returns SessionExecutionHandle (AsyncIterable, not PromiseLike):

  • await handle.result → SendResult when execution completes
  • for await (const event of handle) → stream events

Concurrent calls return THE SAME handle - messages queue, handle resolves when the tick loop settles.

Example ​

typescript
// Await Procedure to get handle, then stream events
const handle = await session.send({ messages: [...] });
for await (const event of handle) {
  console.log(event);
}

// Or get the result directly via ProcedurePromise chaining
const result = await session.send({ messages: [...] }).result;

spawn ​

spawn: Procedure<(component, input?, options?) => SessionExecutionHandle, true>

Defined in: core/src/app/types.ts:1643

Spawn a child session with a different agent/component.

Creates an ephemeral child session, runs it to completion, and returns the same SessionExecutionHandle as session.send().

The child session is NOT registered in the App's session registry. Parent abort propagates to child. Max spawn depth is 10.

By default, child inherits parent's structural options (model, tools, runner, maxTicks). Use options to override any of these.

Param ​

ComponentFunction or JSX element

Param ​

Optional SendInput for the child session

Param ​

Optional overrides for the child's structural options

Example ​

typescript
// Basic spawn
const handle = await session.spawn(ResearchAgent, { messages });

// Spawn with different runner
const handle = await session.spawn(CodeAgent, { messages }, {
  runner: replRunner,
});

status ​

readonly status: SessionStatus

Defined in: core/src/app/types.ts:1521

Current session status

Methods ​

channel() ​

channel(name): Channel

Defined in: core/src/app/types.ts:1816

Get a named channel for pub/sub communication.

Channels allow external code to communicate with running components and vice versa. Components can subscribe to channels using useChannel().

Built-in channels:

  • 'messages': Message queue updates
  • 'tool_confirmation': Tool confirmation requests/responses

Parameters ​

name ​

string

Channel name

Returns ​

Channel

The channel instance

Example ​

typescript
// External code publishes to session
session.channel('custom').publish({ action: 'refresh' });

// Component subscribes
const channel = useChannel('custom');
useEffect(() => channel.subscribe(handleEvent), []);

clearAbort() ​

clearAbort(): void

Defined in: core/src/app/types.ts:1670

Clear the aborted state flag, allowing the session to continue.

Returns ​

void


close() ​

close(): Promise<void>

Defined in: core/src/app/types.ts:1860

Close the session and release resources. Awaits runner cleanup (onDestroy) and child session teardown.

Returns ​

Promise<void>


events() ​

events(): AsyncIterable<StreamEvent>

Defined in: core/src/app/types.ts:1700

Convert EventEmitter to AsyncIterable for the current/next execution.

Call this before send() to capture events as an AsyncIterable. The iterable completes when the execution finishes.

Returns ​

AsyncIterable<StreamEvent>


getRecording() ​

getRecording(): SessionRecording | null

Defined in: core/src/app/types.ts:1770

Get the session recording.

Returns null if recording was never started.

Returns ​

SessionRecording | null

Example ​

typescript
const session = app.session({ recording: 'full' });
await session.render({ query: "Hello!" });

const recording = session.getRecording();
console.log(recording?.snapshots.length); // 1
console.log(recording?.summary.totalUsage);

getSnapshotAt() ​

getSnapshotAt(tick): TickSnapshot | null

Defined in: core/src/app/types.ts:1787

Get a specific tick's snapshot.

Parameters ​

tick ​

number

Tick number (1-indexed)

Returns ​

TickSnapshot | null

The snapshot, or null if not found or recording not enabled

Example ​

typescript
const snapshot = session.getSnapshotAt(2);
if (snapshot) {
  console.log(snapshot.model.output.content);
  console.log(snapshot.tools.calls);
}

getToolDefinitions() ​

getToolDefinitions(): Promise<ToolDefinition[]>

Defined in: core/src/app/types.ts:1825

Get tool definitions for all registered tools.

Returns the provider-compatible ToolDefinition[] (with JSON Schema). Includes ALL tools (model + user + all audience), with audience field set. Mounts the component tree if not already mounted.

Returns ​

Promise<ToolDefinition[]>


inspect() ​

inspect(): SessionInspection

Defined in: core/src/app/types.ts:1725

Inspect the current session state for debugging.

Returns a snapshot of live status, last outputs, aggregated usage, and component/hook summaries. Useful for DevTools integration and debugging mid-execution.

Returns ​

SessionInspection

Example ​

typescript
const session = app.session();
await session.render({ query: "Hello!" });

const info = session.inspect();
console.log('Tick:', info.currentTick);
console.log('Components:', info.components.names);
console.log('Total tokens:', info.totalUsage.totalTokens);

interrupt() ​

interrupt(message?, reason?): void

Defined in: core/src/app/types.ts:1665

Interrupt the current execution, optionally with a message.

If the session is running:

  1. Aborts the current execution
  2. Queues the message (if provided)

If the session is idle:

  1. Queues the message (if provided)

Parameters ​

message? ​

Message

Optional message to queue

reason? ​

string

Optional abort reason

Returns ​

void


mount() ​

mount(): Promise<void>

Defined in: core/src/app/types.ts:1677

Mount the component tree without calling the model. Makes tools and commands available for dispatch. No-op if already mounted.

Returns ​

Promise<void>


notifyParent() ​

notifyParent(message): Promise<void>

Defined in: core/src/app/types.ts:1854

Deliver a message to this session's parent inbox.

Uses parentSessionId to write directly to the inbox storage. Throws if no parentSessionId is set or inbox storage is unavailable.

Parameters ​

message ​

InboxMessageInput

Returns ​

Promise<void>


pushEvent() ​

pushEvent(event): void

Defined in: core/src/app/types.ts:1837

Push an event into this session's event stream.

The event goes through the full enrichment pipeline (id, tick, timestamp, sequence, devtools forwarding) and is delivered to all consumers: onEvent callbacks, EventEmitter listeners, and AsyncIterable readers.

Use this to inject external events (e.g. forwarding confirmations from child sessions that aren't connected via spawn).

Parameters ​

event ​

Record<string, unknown> & object

Returns ​

void


snapshot() ​

snapshot(): SessionSnapshot

Defined in: core/src/app/types.ts:1705

Export session state for persistence.

Returns ​

SessionSnapshot


startRecording() ​

startRecording(mode): void

Defined in: core/src/app/types.ts:1746

Start recording tick snapshots.

If already recording, changes the mode.

Parameters ​

mode ​

RecordingMode

Recording mode ('full' or 'lightweight')

Returns ​

void

Example ​

typescript
const session = app.session();
session.startRecording('full');
await session.render({ query: "Hello!" });
const recording = session.getRecording();

stopRecording() ​

stopRecording(): void

Defined in: core/src/app/types.ts:1753

Stop recording tick snapshots.

The recording is preserved and can still be retrieved with getRecording().

Returns ​

void


submitToolResult() ​

submitToolResult(toolUseId, response): void

Defined in: core/src/app/types.ts:1843

Submit tool confirmation result out-of-band. Used when client sends tool confirmation outside of execution handle.

Parameters ​

toolUseId ​

string

response ​
approved ​

boolean

modifiedArguments? ​

Record<string, unknown>

reason? ​

string

Returns ​

void

Released under the ISC License.