Skip to content

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.

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:

Terminal window
npm install @kuralle-agents/redis-store redis
redis-store.ts
import { 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 }),
});

For Postgres-backed sessions, use @kuralle-agents/postgres-store:

Terminal window
npm install @kuralle-agents/postgres-store pg
import { 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).

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.sessionId;
}
await handle;
}

Flow state — current node, collected fields — lives inside the session under session.agentStates. When you swap session stores, flow state persists with the rest of the session automatically.

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, set, delete methods
}