Sessions & Agent
client.sessions, SessionHandle, runTurn, interrupts, and agent realtime patterns.
On this page10
The agent API is client.sessions plus SessionHandle. HTTP projections
are the source of truth; WebSocket carries invalidation signals and optional
streaming deltas.
Session CRUD
| Method | Description |
|---|---|
list(vaultId, options?) | Promise<Session[]> (optional pageSize via PageOptions) |
get(id, options?) | Session metadata |
create(vaultId, title?, options?) | New session |
delete(id, options?) | Delete |
archive(id, options?) | Archive |
dispatch(params) | One-shot dispatch (202) without a long-lived handle |
handle(sessionId, vaultId, options?) | Open a SessionHandle |
listTasks / createTask / updateTask / deleteTask | Task management |
stop(…) | Stop agent run |
const session = await client.sessions.create(vaultId, 'Discovery session')
const handle = await client.sessions.handle(session.id, vaultId, {
realtime: true, // open WebSocket (default true)
messageLimit: 50,
})Overriding wsUrl
The client derives wsUrl from baseUrl by default (wss scheme, /ws
path). If your agent WebSocket endpoint lives on a different origin, set it
on the client:
const client = new TrickestClient({
token: process.env.TRICKEST_TOKEN,
wsUrl: process.env.TRICKEST_WS_URL,
})SessionHandle
Returned by client.sessions.handle(sessionId, vaultId, options).
| Member | Description |
|---|---|
vaultId, sessionId | Identifiers |
state | Latest SessionStateProjection or null before first refresh |
refresh(opts?) | Manual GET …/state refetch |
subscribe(fn) | Called on each projection update; returns unsubscribe |
subscribeStreaming(fn) | Per-character / tool-input deltas (UI paths) |
send(params) | Dispatch turn → { runId, sessionId, jobId } (202) |
abort(opts?) | Stop current run |
resolveInterrupt(decision, opts?) | Answer permission / approval / ask_user |
getActiveInterrupt() | Pending interrupt or null |
close() | Tear down WS + subscribers |
SessionSendParams
await handle.send({
prompt: 'List my recent workflows',
agentMode: 'agent', // 'agent' | 'plan' | 'ask'
modelId: 'google/gemini-3-flash',
workflowId,
spaceId,
editorMode: 'workflow', // 'workflow' | 'app' | 'agent' | 'database'
autoApprove: true,
signal: abortController.signal,
timeout: 120_000,
})send resolves on 202 Accepted. The answer arrives via subscribe, not the
send promise.
Interactive loop
const handle = await client.sessions.handle(sessionId, vaultId, { realtime: true })
const off = handle.subscribe((projection, change) => {
console.log('phase', projection.run.phase, change.sources)
})
await handle.refresh()
const { runId } = await handle.send({
prompt: 'Summarize open findings',
autoApprove: true,
})
// … wait for terminal phase in subscribe callback …
off()
handle.close()Streaming frames (UI)
handle.subscribeStreaming((frame) => {
if (frame.type === 'text_stream_delta') process.stdout.write(frame.delta)
if (frame.type === 'text_stream_end') console.log('\n', frame.finalStatus)
})Frame types include text_stream_delta, thinking_stream_delta,
tool_input_stream_delta, text_stream_end.
runTurn (headless one-shot)
For scripts and CLI tools that want "send prompt, wait, return answer":
import { runTurn } from '@trickest/sdk'
const handle = await client.sessions.handle(sessionId, vaultId)
const summary = await runTurn(handle, {
prompt: 'Build a discovery workflow for example.com',
agentMode: 'agent',
}, { timeoutMs: 120_000 })
if (summary.success) {
console.log(summary.answer)
for (const tc of summary.toolCalls) {
console.log(tc.name, tc.status, tc.result)
}
} else {
console.error(summary.phase, summary.errorMessage)
}
handle.close()runTurn does not close the handle. Call handle.close() yourself.
Interrupts
const interrupt = handle.getActiveInterrupt()
if (interrupt?.type === 'permission') {
await handle.resolveInterrupt({
type: 'permission',
id: interrupt.id,
behavior: 'allow',
rememberFor: 'session',
})
}InterruptResolution types: permission, approval, plan_approval, mode_switch,
ask_user.
Exported projection types
Re-exported from @trickest/sdk for typing UI and automation:
SessionStateProjection, MessageProjection, ToolCallProjection, RunProjection,
StreamingFrame, InterruptProjection, and related enums. Use your IDE on
import type { … } from '@trickest/sdk'.