Skip to content

Documentation / @agentick/core / Session

Interface: Session<P>

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

Extends

  • EventEmitter

Type Parameters

P

P = { }

Properties

append

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

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

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

children

readonly children: readonly Session<{ }>[]

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

Active child sessions (currently running spawns).


currentTick

readonly currentTick: number

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

Current tick number


dispatch

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

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

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:1547

Unique session ID


isAborted

readonly isAborted: boolean

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

Whether the session has been aborted


isTerminal

readonly isTerminal: boolean

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

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


metadata

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

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

Immutable identity labels set at creation time.


parent

readonly parent: Session<{ }> | null

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

Parent session, or null for root sessions.


parentSessionId

readonly parentSessionId: string | null

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

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:1601

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:1579

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


render

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

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

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:1589

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:1625

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;

skill

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

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

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


spawn

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

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

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:1550

Current session status


tools

readonly tools: SessionToolsProxy

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

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

Methods

channel()

channel(name): Channel

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

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:1699

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

Returns

void


close()

close(): Promise<void>

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

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:1866

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:1936

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:1953

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:1991

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:1891

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:1694

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:1706

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:2020

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>


observe()

observe(input): Promise<void>

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

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

The event becomes part of the conversation history without triggering a tick. 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: "/foo.ts" });

pushEvent()

pushEvent(event): void

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

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


shell()

shell(command): Promise<string>

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

Run a shell command in the agent's sandbox. Output is the joined text of all text blocks the <Bash> tool emits — including any [stderr] / [exit code: N] annotations on failure. Callers needing structured stdout/stderr/exitCode should dispatch bash directly.

Parameters

command

string

Returns

Promise<string>

See

Session.shell — JSDoc on the implementation has the full output shape contract.

Sugar over dispatch("bash", { command }). Returns the joined text from the resulting content blocks. Requires a <Bash> tool (or any tool registered as bash accepting { command: string }) to be mounted.

Example

typescript
const out = await session.shell("ls -la");

snapshot()

snapshot(): SessionSnapshot

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

Export session state for persistence.

Returns

SessionSnapshot


startRecording()

startRecording(mode): void

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

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:1919

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:2009

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.