Skip to content

Documentation / @agentick/core / SessionImpl

Class: SessionImpl<P>

Defined in: core/src/app/session.ts:195

Session implementation.

A session manages the execution lifecycle: compile JSX, call model, execute tools. Component state (hooks, signals) persists across ticks within a session.

Extends

  • EventEmitter

Type Parameters

P

P = { }

Implements

Constructors

Constructor

new SessionImpl<P>(Component, appOptions, sessionOptions?): SessionImpl<P>

Defined in: core/src/app/session.ts:305

Parameters

Component

ComponentFunction<P>

appOptions

AppOptions

sessionOptions?

SessionOptions = {}

Returns

SessionImpl<P>

Overrides

EventEmitter.constructor

Properties

append

append: Procedure<(entry, opts?) => Promise<void | SessionExecutionHandle>, true>

Defined in: core/src/app/session.ts:451

Append a timeline entry directly to the session timeline.

The primitive timeline write — bypasses the next-tick queue (queue) entirely. The entry lands in the timeline immediately, components reading the timeline see it, and the model sees it on the next compile. Emits entry_committed.

Use this for "ambient context" (events, observations, system facts) that should be part of the conversation history without being treated as a pending user turn.

Param

The timeline entry to append. An id is auto-assigned when missing.

Param

When true, runs a tick after appending so the model can act on the new entry. Defaults to false.

Returns

A SessionExecutionHandle when trigger: true, otherwise void.

Example

typescript
// Direct event entry, no execution
await session.append({
  kind: "message",
  message: { role: "event", eventType: "file_opened", content: [...] },
});

Implementation of

Session.append


dispatch

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

Defined in: core/src/app/session.ts:447

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.

Implementation of

Session.dispatch


id

readonly id: string

Defined in: core/src/app/session.ts:196

Unique session ID

Implementation of

Session.id


queue

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

Defined in: core/src/app/session.ts:436

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)

Implementation of

Session.queue


render

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

Defined in: core/src/app/session.ts:438

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;

Implementation of

Session.render


send

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

Defined in: core/src/app/session.ts:437

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;

Implementation of

Session.send


skill

skill: Procedure<<TInput, TResult>(skill, opts) => Promise<TResult>, true>

Defined in: core/src/app/session.ts:458

Run a skill — a scoped sub-agent invocation with caller-typed results.

The skill defines the workflow (instructions + input contract + allowed tools); the caller decides what shape to extract via opts.result. When result is given, a transient submit tool is registered whose input schema IS result; the agent is instructed to call it. When result is omitted, the skill returns the model's final assistant text.

Examples

typescript
const Triage = defineSkill({
  name: "triage",
  instructions: "Investigate, decide on action, submit.",
  input: z.object({ issueNumber: z.number() }),
  tools: ["search", "read_file"],
});

const t = await session.skill(Triage, {
  args: { issueNumber: 42 },
  result: z.object({ fixApplied: z.boolean() }),
});
// t is typed as { fixApplied: boolean }
typescript
const text = await session.skill(Summarize, { args: { content } });
// text is string — the final assistant response

Throws when result is given and the model does not call submit within maxTicks (defaults to 10).

Implementation of

Session.skill


spawn

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

Defined in: core/src/app/session.ts:439

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,
});

Implementation of

Session.spawn

Accessors

children

Get Signature

get children(): readonly Session<{ }>[]

Defined in: core/src/app/session.ts:401

Active child sessions (currently running spawns).

Returns

readonly Session<{ }>[]

Active child sessions (currently running spawns).

Implementation of

Session.children


currentTick

Get Signature

get currentTick(): number

Defined in: core/src/app/session.ts:381

Current tick number

Returns

number

Current tick number

Implementation of

Session.currentTick


isAborted

Get Signature

get isAborted(): boolean

Defined in: core/src/app/session.ts:385

Whether the session has been aborted

Returns

boolean

Whether the session has been aborted

Implementation of

Session.isAborted


isTerminal

Get Signature

get isTerminal(): boolean

Defined in: core/src/app/session.ts:372

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

Returns

boolean

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

Implementation of

Session.isTerminal


metadata

Get Signature

get metadata(): Readonly<Record<string, unknown>>

Defined in: core/src/app/session.ts:397

Immutable identity labels set at creation time.

Returns

Readonly<Record<string, unknown>>

Immutable identity labels set at creation time.

Implementation of

Session.metadata


parent

Get Signature

get parent(): Session<{ }> | null

Defined in: core/src/app/session.ts:389

Parent session, or null for root sessions.

Returns

Session<{ }> | null

Parent session, or null for root sessions.

Implementation of

Session.parent


parentSessionId

Get Signature

get parentSessionId(): string | null

Defined in: core/src/app/session.ts:393

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.
Returns

string | null

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.

Implementation of

Session.parentSessionId


queuedMessages

Get Signature

get queuedMessages(): readonly Message[]

Defined in: core/src/app/session.ts:405

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

Returns

readonly Message[]

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

Implementation of

Session.queuedMessages


schedulerState

Get Signature

get schedulerState(): SchedulerState | null

Defined in: core/src/app/session.ts:428

Observable scheduler state for DevTools.

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

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

Example
typescript
// In DevTools
effect(() => {
  const state = session.schedulerState?.();
  if (state) {
    console.log(`Status: ${state.status}, reconciles: ${state.reconcileCount}`);
  }
});
Returns

SchedulerState | null

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.

Implementation of

Session.schedulerState


status

Get Signature

get status(): SessionStatus

Defined in: core/src/app/session.ts:367

Current session status

Returns

SessionStatus

Current session status

Implementation of

Session.status


tools

Get Signature

get tools(): SessionToolsProxy

Defined in: core/src/app/session.ts:1474

Programmatic dispatch surface — session.tools.<name>(input). See Session.tools for the full contract.

Returns

SessionToolsProxy

Programmatic tool dispatch surface.

session.tools.<name>(input) is sugar for session.dispatch(name, input). Property access composes dot-paths, so session.tools.knowify.search(args) dispatches the tool registered as "knowify.search".

Returns ContentBlock[] from the tool handler.

Example

typescript
const blocks = await session.tools.bash({ command: "pwd" });
const hits = await session.tools.knowify.search({ q: "ledger" });

Implementation of

Session.tools

Methods

channel()

channel(name): Channel

Defined in: core/src/app/session.ts:1331

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), []);

Implementation of

Session.channel


clearAbort()

clearAbort(): void

Defined in: core/src/app/session.ts:1376

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

Returns

void

Implementation of

Session.clearAbort


close()

close(): Promise<void>

Defined in: core/src/app/session.ts:2318

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

Returns

Promise<void>

Implementation of

Session.close


events()

events(): AsyncIterable<StreamEvent>

Defined in: core/src/app/session.ts:1591

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>

Implementation of

Session.events


getRecording()

getRecording(): SessionRecording | null

Defined in: core/src/app/session.ts:1932

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);

Implementation of

Session.getRecording


getSnapshotAt()

getSnapshotAt(tick): TickSnapshot | null

Defined in: core/src/app/session.ts:1941

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);
}

Implementation of

Session.getSnapshotAt


getToolDefinitions()

getToolDefinitions(): Promise<ToolDefinition[]>

Defined in: core/src/app/session.ts:1487

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[]>

Implementation of

Session.getToolDefinitions


inspect()

inspect(): SessionInspection

Defined in: core/src/app/session.ts:1829

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);

Implementation of

Session.inspect


interrupt()

interrupt(message?, reason?): void

Defined in: core/src/app/session.ts:1356

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

Implementation of

Session.interrupt


mount()

mount(): Promise<void>

Defined in: core/src/app/session.ts:1380

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

Returns

Promise<void>

Implementation of

Session.mount


notifyParent()

notifyParent(message): Promise<void>

Defined in: core/src/app/session.ts:2304

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>

Implementation of

Session.notifyParent


observe()

observe(input): Promise<void>

Defined in: core/src/app/session.ts:1409

Append an event entry (message with role: "event") to the timeline as ambient context. Sugar over Session.append.

Use for facts the agent should know but that aren't a user turn: file_opened, mcp_resource_changed, user_idle, etc.

Parameters

input
content

string | ContentBlock[]

metadata?

Record<string, unknown>

type

string

Returns

Promise<void>

Example

typescript
session.observe({ type: "file_opened", content: [{ type: "text", text: "/foo.ts" }] });

Implementation of

Session.observe


processInboxMessages()

processInboxMessages(): Promise<void>

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

Internal

Process all pending inbox messages. Called by App.processInbox().

Returns

Promise<void>


pushEvent()

pushEvent(event): void

Defined in: core/src/app/session.ts:1625

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

Implementation of

Session.pushEvent


setInboxStorage()

setInboxStorage(storage): void

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

Internal

Connect this session to an inbox storage backend. Subscribes to notifications and drains any pre-existing pending messages.

Parameters

storage

InboxStorage

Returns

void


setPersistCallback()

setPersistCallback(callback): void

Defined in: core/src/app/session.ts:1744

Internal

Set the auto-persist callback. Called by the App when a store is configured.

Parameters

callback

(snapshot) => Promise<void>

Returns

void


setSnapshotForResolve()

setSnapshotForResolve(snapshot): void

Defined in: core/src/app/session.ts:1821

Internal

Set a snapshot to be applied/resolved when compilation infrastructure is created.

Parameters

snapshot

SessionSnapshot

Returns

void


shell()

shell(command): Promise<string>

Defined in: core/src/app/session.ts:1448

Run a shell command via the registered bash tool.

Sugar over dispatch("bash", { command }). Joins text-typed content blocks with newlines and returns the resulting string.

Output shape: the bundled <Bash> tool emits stdout, stderr, and exit-code annotations as a single text block when the command fails:

stdout content [stderr] stderr content [exit code: 1]

The full string is returned as-is — no parsing or stripping. Callers that need structured stdout/stderr/exitCode should dispatch("bash", ...) directly and inspect the content blocks, or wait for the typed shell-result variant on a future phase.

Parameters

command

string

Returns

Promise<string>

Implementation of

Session.shell


snapshot()

snapshot(): SessionSnapshot

Defined in: core/src/app/session.ts:1722

Export session state for persistence.

Returns

SessionSnapshot

Implementation of

Session.snapshot


startRecording()

startRecording(mode): void

Defined in: core/src/app/session.ts:1897

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();

Implementation of

Session.startRecording


stopRecording()

stopRecording(): void

Defined in: core/src/app/session.ts:1921

Stop recording tick snapshots.

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

Returns

void

Implementation of

Session.stopRecording


submitToolResult()

submitToolResult(toolUseId, response): void

Defined in: core/src/app/session.ts:1340

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

Implementation of

Session.submitToolResult

Released under the ISC License.