Skip to main content

Sessions

Sessions in RadarOS track conversation history and arbitrary state per conversation. The SessionManager stores raw messages and replays them as context to the LLM on each run.

How It Works

Every time you call agent.run() or agent.stream() with a sessionId, the agent:
  1. Loads the session’s message history from storage
  2. Includes the history as conversation context to the LLM
  3. After the run, appends the new user/assistant exchange to the session
If you use the same sessionId across multiple calls, the agent maintains a continuous conversation.
const agent = new Agent({
  name: "assistant",
  model: openai("gpt-4o"),
  storage: new InMemoryStorage(),
});

await agent.run("My name is Bob.", { sessionId: "conv-1" });
const result = await agent.run("What's my name?", { sessionId: "conv-1" });
// Agent knows "Bob" from the first message
If sessionId is omitted, a new UUID is generated per run — each call is a fresh conversation.

Session Object

PropertyTypeDescription
sessionIdstringUnique identifier for the session
userIdstring?Optional user identifier
messagesChatMessage[]Conversation history
stateRecord<string, unknown>Arbitrary key-value state
createdAtDateWhen the session was created
updatedAtDateWhen the session was last updated

History Overflow

When numHistoryRuns is set on the agent, the session automatically trims older messages to stay within the limit. This prevents the context window from growing unboundedly.
const agent = new Agent({
  name: "assistant",
  model: openai("gpt-4o"),
  storage,
  numHistoryRuns: 25,  // keep last 25 exchanges (50 messages)
});
When messages overflow, if a Memory instance is configured, the trimmed messages are sent to Memory for LLM-powered summarization. This way, old conversation context is preserved as summaries rather than lost.

Token-Based Trimming

For tighter control, set maxContextTokens to automatically trim history based on estimated token count:
const agent = new Agent({
  name: "assistant",
  model: openai("gpt-4o"),
  storage,
  maxContextTokens: 4000,
});
The agent estimates tokens for the system prompt, current input, and history. History is trimmed from oldest first until everything fits within the budget.

Session State

Sessions support arbitrary state for persisting data across turns. Access it via RunContext.sessionState in hooks or tools:
const agent = new Agent({
  name: "assistant",
  model: openai("gpt-4o"),
  storage: new InMemoryStorage(),
  hooks: {
    beforeRun: async (ctx) => {
      const count = ctx.getState<number>("runCount") ?? 0;
      ctx.setState("runCount", count + 1);
    },
  },
});
State is automatically persisted via updateState after each run.

SessionManager API

SessionManager is used internally by agents but can also be used standalone:
import { SessionManager, InMemoryStorage } from "@radaros/core";

const sm = new SessionManager(new InMemoryStorage(), {
  maxMessages: 50,  // optional: auto-trim when exceeded
});

const session = await sm.getOrCreate("conv-1", "user-42");
const { overflow } = await sm.appendMessages("conv-1", [
  { role: "user", content: "Hello" },
  { role: "assistant", content: "Hi there!" },
]);
// overflow contains trimmed messages (empty if under maxMessages)

const history = await sm.getHistory("conv-1", 20); // last 20 messages
await sm.updateState("conv-1", { topic: "greetings" });
await sm.deleteSession("conv-1");

Storage Drivers

InMemoryStorage

Default. Sessions live in process memory. Lost on restart. Good for development.

MongoDBStorage

Persistent sessions in MongoDB. Use for production.

SqliteStorage

Persistent sessions in SQLite. Good for single-node deployments.

PostgresStorage

Persistent sessions in PostgreSQL. Use for scalable deployments.
import { Agent, MongoDBStorage, openai } from "@radaros/core";

const storage = new MongoDBStorage(
  "mongodb://localhost:27017",
  "myapp",
  "sessions"
);
await storage.initialize();

const agent = new Agent({
  name: "assistant",
  model: openai("gpt-4o"),
  storage,
});

Session vs Memory vs User Memory

LayerStoresKeyed byPurpose
SessionRaw messages + statesessionIdImmediate conversation history, replayed to LLM
MemoryLLM summariessessionIdLong-term context from overflowed messages
User MemoryPersonal factsuserIdCross-session personalization
Session is always active. Memory kicks in when history overflows. User Memory persists facts about a person across all their sessions. See Memory and User Memory for details.