Sessions & State
Kuralle uses a SessionStore to persist conversation history and per-agent state. Every runtime.run() call retrieves the session, appends the new turn, and saves it back.
Default: MemoryStore
Section titled “Default: MemoryStore”createRuntime defaults to an in-process MemoryStore. It's zero-config and suitable for development and short-lived processes:
import { createRuntime } from '@kuralle-agents/core';
const runtime = createRuntime({ agents: [agent], defaultAgentId: 'support', // sessionStore defaults to new MemoryStore()});Sessions live in memory and are lost on process restart.
For persistent sessions, pass a RedisSessionStore from @kuralle-agents/redis-store:
npm install @kuralle-agents/redis-store redisimport { createRuntime, defineAgent } from '@kuralle-agents/core';import { RedisSessionStore } from '@kuralle-agents/redis-store';import { createClient } from 'redis';import { openai } from '@ai-sdk/openai';
const client = createClient({ url: process.env.REDIS_URL });await client.connect();
const agent = defineAgent({ id: 'support', instructions: 'You are a helpful support agent.', model: openai('gpt-4o-mini'),});
const runtime = createRuntime({ agents: [agent], defaultAgentId: 'support', sessionStore: new RedisSessionStore({ client }),});Postgres
Section titled “Postgres”For Postgres-backed sessions, use @kuralle-agents/postgres-store:
npm install @kuralle-agents/postgres-store pgimport { Pool } from 'pg';import { createRuntime } from '@kuralle-agents/core';import { PostgresSessionStore } from '@kuralle-agents/postgres-store';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const runtime = createRuntime({ agents: [agent], defaultAgentId: 'support', sessionStore: new PostgresSessionStore({ client: pool }),});By default, PostgresSessionStore creates the sessions table on first use (autoMigrate: true).
Session IDs
Section titled “Session IDs”The runtime auto-assigns a session ID when none is provided. Pass sessionId back on subsequent turns to continue the same conversation:
let sessionId: string | undefined;
async function chat(input: string) { const handle = runtime.run({ input, sessionId }); for await (const part of handle.events) { if (part.type === 'done') sessionId = part.payload.sessionId; } await handle;}Flow state
Section titled “Flow state”Flow state — active flow, current node, collected fields — lives on the durable run. With the default SessionRunStore, runs (state plus effect journal) persist inside the session under a durableRuns key, so when you swap session stores, flow state moves with the rest of the session automatically. A dedicated runStore on the harness config (e.g. PostgresRunStore) journals runs outside the session instead — see Durable Execution.
Custom stores
Section titled “Custom stores”The SessionStore interface is exported from @kuralle-agents/core. Implement it to back sessions with any storage system:
import type { SessionStore } from '@kuralle-agents/core';
class MyStore implements SessionStore { // get, save, delete, list — the full interface}