or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

agents.mderrors.mdguardrails.mdhandoffs.mdindex.mdmcp.mdmodels.mdrealtime.mdsessions.mdtools.mdtracing.md
tile.json

sessions.mddocs/

Session Management

Persistent conversation history storage with multiple backend options.

Capabilities

Session Interface

Base interface for implementing conversation history storage.

/**
 * Session interface for persistent conversation history
 */
interface Session {
  /**
   * Get unique session identifier
   * @returns Session ID
   */
  getSessionId(): Promise<string>;

  /**
   * Get conversation history items
   * @param limit - Maximum number of items to return
   * @returns Array of agent input items
   */
  getItems(limit?: number): Promise<AgentInputItem[]>;

  /**
   * Add new items to the session history
   * @param items - Items to add
   */
  addItems(items: AgentInputItem[]): Promise<void>;

  /**
   * Remove and return the last item from history
   * @returns Last item or undefined if empty
   */
  popItem(): Promise<AgentInputItem | undefined>;

  /**
   * Clear all session history
   */
  clearSession(): Promise<void>;
}

Usage Examples:

import { Agent, run, Session } from '@openai/agents';

// Using a session with run
class CustomSession implements Session {
  private items: AgentInputItem[] = [];
  private sessionId: string = 'session-' + Date.now();

  async getSessionId(): Promise<string> {
    return this.sessionId;
  }

  async getItems(limit?: number): Promise<AgentInputItem[]> {
    if (limit) {
      return this.items.slice(-limit);
    }
    return this.items;
  }

  async addItems(items: AgentInputItem[]): Promise<void> {
    this.items.push(...items);
  }

  async popItem(): Promise<AgentInputItem | undefined> {
    return this.items.pop();
  }

  async clearSession(): Promise<void> {
    this.items = [];
  }
}

const session = new CustomSession();
const agent = new Agent({
  name: 'Assistant',
  instructions: 'You are helpful',
});

// First message
const result1 = await run(agent, 'My name is Alice', { session });
console.log(result1.finalOutput);

// Second message (with history)
const result2 = await run(agent, 'What is my name?', { session });
console.log(result2.finalOutput); // Should remember "Alice"

// Check session history
const history = await session.getItems();
console.log('History items:', history.length);

// Clear session
await session.clearSession();

MemorySession

In-memory session implementation for development and testing.

/**
 * In-memory session implementation (not persistent)
 * For development and testing only
 */
class MemorySession implements Session {
  constructor(options?: MemorySessionOptions);

  getSessionId(): Promise<string>;
  getItems(limit?: number): Promise<AgentInputItem[]>;
  addItems(items: AgentInputItem[]): Promise<void>;
  popItem(): Promise<AgentInputItem | undefined>;
  clearSession(): Promise<void>;
}

interface MemorySessionOptions {
  /** Initial session ID */
  sessionId?: string;

  /** Initial history items */
  initialItems?: AgentInputItem[];
}

Usage Examples:

import { Agent, run, MemorySession } from '@openai/agents';

// Basic memory session
const session = new MemorySession();

const agent = new Agent({
  name: 'ChatAgent',
  instructions: 'You are a conversational assistant',
});

// Conversation with memory
const result1 = await run(agent, 'I like pizza', { session });
const result2 = await run(agent, 'What food do I like?', { session });
console.log(result2.finalOutput); // Should mention pizza

// Memory session with initial ID
const namedSession = new MemorySession({
  sessionId: 'user-123-session',
});

// Memory session with initial history
import { user, assistant } from '@openai/agents';

const preloadedSession = new MemorySession({
  initialItems: [
    user('Hello'),
    assistant('Hi! How can I help you?'),
    user('Tell me about sessions'),
  ],
});

const result3 = await run(agent, 'Continue from where we left off', {
  session: preloadedSession,
});

// Access session data
const sessionId = await session.getSessionId();
console.log('Session ID:', sessionId);

const history = await session.getItems();
console.log('History length:', history.length);

const limitedHistory = await session.getItems(5); // Last 5 items
console.log('Last 5 items:', limitedHistory.length);

// Modify session
const lastItem = await session.popItem();
console.log('Removed item:', lastItem);

await session.clearSession();
console.log('Session cleared');

OpenAIConversationsSession

Session implementation using OpenAI's Conversations API for persistent storage.

/**
 * Session backed by OpenAI Conversations API
 * Provides persistent, scalable conversation storage
 */
class OpenAIConversationsSession implements Session {
  constructor(options?: OpenAIConversationsSessionOptions);

  getSessionId(): Promise<string>;
  getItems(limit?: number): Promise<AgentInputItem[]>;
  addItems(items: AgentInputItem[]): Promise<void>;
  popItem(): Promise<AgentInputItem | undefined>;
  clearSession(): Promise<void>;
}

interface OpenAIConversationsSessionOptions {
  /** Existing conversation ID */
  conversationId?: string;

  /** OpenAI client instance */
  client?: OpenAI;

  /** API key (if not using client) */
  apiKey?: string;

  /** Base URL (if not using client) */
  baseURL?: string;

  /** Organization ID */
  organization?: string;

  /** Project ID */
  project?: string;
}

/**
 * Create a new conversation session and return its ID
 * @param client - OpenAI client (optional)
 * @returns Conversation ID string for the new session
 */
function startOpenAIConversationsSession(
  client?: OpenAI
): Promise<string>;

Usage Examples:

import { Agent, run, OpenAIConversationsSession, startOpenAIConversationsSession } from '@openai/agents';
import OpenAI from 'openai';

// Create new conversation (returns conversation ID)
const conversationId = await startOpenAIConversationsSession();
console.log('Conversation ID:', conversationId);

// Create session with the conversation ID
const session = new OpenAIConversationsSession({
  conversationId,
});

const agent = new Agent({
  name: 'PersistentAgent',
  instructions: 'You are a helpful assistant with persistent memory',
});

// First conversation
const result1 = await run(agent, 'My favorite color is blue', { session });

// Resume existing conversation later (even from different process)
const resumedSession = new OpenAIConversationsSession({
  conversationId,
});

const result2 = await run(agent, 'What is my favorite color?', {
  session: resumedSession,
});
console.log(result2.finalOutput); // Should remember "blue"

// With custom OpenAI client
const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  organization: 'org-123',
});

const customConversationId = await startOpenAIConversationsSession(client);

// With API key directly
const directSession = new OpenAIConversationsSession({
  apiKey: process.env.OPENAI_API_KEY,
  baseURL: 'https://api.openai.com/v1',
});

// Access conversation history
const history = await session.getItems();
console.log('Full history:', history.length);

const recent = await session.getItems(10); // Last 10 items
console.log('Recent history:', recent.length);

// Clear conversation
await session.clearSession();

Session with Run Options

Use sessions with the run function and Runner class.

interface RunOptions<TContext = any> {
  /** Session for persistent conversation history */
  session?: Session;

  /** Other run options... */
}

Usage Examples:

import { Agent, run, Runner, MemorySession } from '@openai/agents';

const session = new MemorySession();
const agent = new Agent({
  name: 'ConversationalAgent',
  instructions: 'You are conversational and remember context',
});

// With run function
const result1 = await run(agent, 'I live in Tokyo', { session });
const result2 = await run(agent, 'What city do I live in?', { session });

// With Runner instance
const runner = new Runner({
  workflowName: 'SessionDemo',
});

const result3 = await runner.run(agent, 'My job is engineer', { session });
const result4 = await runner.run(agent, 'What is my job?', { session });

// Multiple sessions
const session1 = new MemorySession({ sessionId: 'user-1' });
const session2 = new MemorySession({ sessionId: 'user-2' });

await run(agent, 'My name is Alice', { session: session1 });
await run(agent, 'My name is Bob', { session: session2 });

const result5 = await run(agent, 'What is my name?', { session: session1 });
console.log(result5.finalOutput); // "Alice"

const result6 = await run(agent, 'What is my name?', { session: session2 });
console.log(result6.finalOutput); // "Bob"

Session Input Callback

Customize how session history is loaded and processed.

interface RunnerConfig<TContext = any> {
  /**
   * Customize session history handling
   * Called before each agent run with session
   */
  sessionInputCallback?: SessionInputCallback;
}

type SessionInputCallback = (
  input: AgentInputItem[],
  session: Session
) => Promise<AgentInputItem[]>;

Usage Examples:

import { Agent, Runner, MemorySession, AgentInputItem } from '@openai/agents';

// Limit session history
const runner = new Runner({
  sessionInputCallback: async (input, session) => {
    // Only keep last 20 messages
    const history = await session.getItems();
    return history.slice(-20);
  },
});

const session = new MemorySession();
const agent = new Agent({
  name: 'LimitedHistoryAgent',
  instructions: 'You are helpful',
});

await runner.run(agent, 'Hello', { session });

// Filter session history
const filteringRunner = new Runner({
  sessionInputCallback: async (input, session) => {
    const history = await session.getItems();

    // Remove system messages from history
    return history.filter(item => item.type !== 'system_message');
  },
});

// Transform session history
const transformRunner = new Runner({
  sessionInputCallback: async (input, session) => {
    const history = await session.getItems();

    // Summarize old messages
    if (history.length > 50) {
      const summary = '... [Earlier conversation summarized] ...';
      const recentHistory = history.slice(-30);

      return [
        { type: 'system_message', content: summary } as AgentInputItem,
        ...recentHistory,
      ];
    }

    return history;
  },
});

Session History Management

Manipulate session history directly.

Usage Examples:

import { Agent, run, MemorySession, user, assistant } from '@openai/agents';

const session = new MemorySession();

// Pre-populate session
await session.addItems([
  user('Hello'),
  assistant('Hi! How can I help?'),
]);

const agent = new Agent({
  name: 'Agent',
  instructions: 'You are helpful',
});

// Continue from pre-populated history
const result = await run(agent, 'What did I say first?', { session });
console.log(result.finalOutput); // Should mention "Hello"

// Get history
const allHistory = await session.getItems();
console.log('Total items:', allHistory.length);

const lastThree = await session.getItems(3);
console.log('Last 3 items:', lastThree);

// Remove last item
const removed = await session.popItem();
console.log('Removed:', removed);

// Add multiple items
await session.addItems([
  user('Additional message 1'),
  user('Additional message 2'),
]);

// Clear everything
await session.clearSession();
const empty = await session.getItems();
console.log('After clear:', empty.length); // 0

Multi-Turn Conversations

Build multi-turn conversations with session context.

Usage Examples:

import { Agent, run, MemorySession } from '@openai/agents';

const session = new MemorySession();
const agent = new Agent({
  name: 'TravelAgent',
  instructions: 'You are a travel booking assistant',
});

// Turn 1: Gather destination
const turn1 = await run(
  agent,
  'I want to book a trip',
  { session }
);
console.log(turn1.finalOutput); // "Where would you like to go?"

// Turn 2: Gather dates
const turn2 = await run(
  agent,
  'I want to go to Paris',
  { session }
);
console.log(turn2.finalOutput); // "When would you like to travel?"

// Turn 3: Gather preferences
const turn3 = await run(
  agent,
  'Next month from the 15th to the 20th',
  { session }
);
console.log(turn3.finalOutput); // "What type of accommodation?"

// Turn 4: Confirm
const turn4 = await run(
  agent,
  'A hotel near the Eiffel Tower',
  { session }
);
console.log(turn4.finalOutput); // Confirmation with all details

// Review complete conversation
const history = await session.getItems();
console.log('Conversation turns:', history.length);

Session Persistence Patterns

Common patterns for session storage.

Usage Examples:

import { Agent, run, OpenAIConversationsSession, MemorySession } from '@openai/agents';

// Pattern 1: Per-user sessions
const userSessions = new Map<string, OpenAIConversationsSession>();

async function getUserSession(userId: string): Promise<OpenAIConversationsSession> {
  if (!userSessions.has(userId)) {
    const session = await startOpenAIConversationsSession();
    userSessions.set(userId, session);
  }
  return userSessions.get(userId)!;
}

const agent = new Agent({
  name: 'UserAgent',
  instructions: 'You are helpful',
});

const aliceSession = await getUserSession('alice');
await run(agent, 'Hello', { session: aliceSession });

// Pattern 2: Session expiry
class ExpiringSession implements Session {
  private session: MemorySession;
  private lastAccess: number;
  private ttlMs: number = 30 * 60 * 1000; // 30 minutes

  constructor() {
    this.session = new MemorySession();
    this.lastAccess = Date.now();
  }

  private checkExpiry() {
    if (Date.now() - this.lastAccess > this.ttlMs) {
      this.session.clearSession();
    }
    this.lastAccess = Date.now();
  }

  async getSessionId(): Promise<string> {
    this.checkExpiry();
    return this.session.getSessionId();
  }

  async getItems(limit?: number): Promise<AgentInputItem[]> {
    this.checkExpiry();
    return this.session.getItems(limit);
  }

  async addItems(items: AgentInputItem[]): Promise<void> {
    this.checkExpiry();
    return this.session.addItems(items);
  }

  async popItem(): Promise<AgentInputItem | undefined> {
    this.checkExpiry();
    return this.session.popItem();
  }

  async clearSession(): Promise<void> {
    return this.session.clearSession();
  }
}

// Pattern 3: Database-backed session
import { Database } from 'some-database-library';

class DatabaseSession implements Session {
  private db: Database;
  private sessionId: string;

  constructor(db: Database, sessionId: string) {
    this.db = db;
    this.sessionId = sessionId;
  }

  async getSessionId(): Promise<string> {
    return this.sessionId;
  }

  async getItems(limit?: number): Promise<AgentInputItem[]> {
    const query = limit
      ? `SELECT * FROM session_history WHERE session_id = ? ORDER BY created_at DESC LIMIT ?`
      : `SELECT * FROM session_history WHERE session_id = ? ORDER BY created_at ASC`;

    const params = limit ? [this.sessionId, limit] : [this.sessionId];
    const rows = await this.db.query(query, params);

    return rows.map(row => JSON.parse(row.item_data));
  }

  async addItems(items: AgentInputItem[]): Promise<void> {
    const query = `INSERT INTO session_history (session_id, item_data, created_at) VALUES (?, ?, ?)`;

    for (const item of items) {
      await this.db.execute(query, [
        this.sessionId,
        JSON.stringify(item),
        Date.now(),
      ]);
    }
  }

  async popItem(): Promise<AgentInputItem | undefined> {
    const items = await this.getItems(1);
    if (items.length === 0) return undefined;

    await this.db.execute(
      `DELETE FROM session_history WHERE session_id = ? ORDER BY created_at DESC LIMIT 1`,
      [this.sessionId]
    );

    return items[0];
  }

  async clearSession(): Promise<void> {
    await this.db.execute(
      `DELETE FROM session_history WHERE session_id = ?`,
      [this.sessionId]
    );
  }
}

Session with Streaming

Use sessions with streaming responses.

Usage Examples:

import { Agent, run, MemorySession } from '@openai/agents';

const session = new MemorySession();
const agent = new Agent({
  name: 'StreamingAgent',
  instructions: 'You are helpful',
});

// First message with streaming
const stream1 = run(agent, 'Tell me a story', {
  session,
  stream: true,
});

for await (const event of stream1) {
  if (event.type === 'message_output_created') {
    process.stdout.write(event.item.message.content);
  }
}

await stream1.completed;

// Second message with streaming (includes history)
const stream2 = run(agent, 'Continue the story', {
  session,
  stream: true,
});

for await (const event of stream2) {
  if (event.type === 'message_output_created') {
    process.stdout.write(event.item.message.content);
  }
}

await stream2.completed;

// Check accumulated history
const history = await session.getItems();
console.log('Messages in session:', history.length);