|
| 1 | +--- |
| 2 | +title: Sessions |
| 3 | +description: Persist multi-turn conversation history so agents can resume context across runs. |
| 4 | +--- |
| 5 | + |
| 6 | +import { Code } from '@astrojs/starlight/components'; |
| 7 | +import sessionsQuickstart from '../../../../../examples/docs/sessions/basicSession.ts?raw'; |
| 8 | +import manageHistory from '../../../../../examples/docs/sessions/manageHistory.ts?raw'; |
| 9 | +import customSession from '../../../../../examples/docs/sessions/customSession.ts?raw'; |
| 10 | +import sessionInputCallback from '../../../../../examples/docs/sessions/sessionInputCallback.ts?raw'; |
| 11 | + |
| 12 | +Sessions give the Agents SDK a **persistent memory layer**. All you need is any |
| 13 | +object that implements the `Session` interface—pass it to `Runner.run` and the |
| 14 | +SDK will handle the rest. When a session is present, the runner automatically: |
| 15 | + |
| 16 | +1. Fetches previously stored conversation items and prepends them to the next turn. |
| 17 | +2. Persists new user input and assistant output after each run completes. |
| 18 | +3. Keeps the session available for future turns, whether you call the runner with |
| 19 | + new user text or resume from an interrupted `RunState`. |
| 20 | + |
| 21 | +This removes the need to manually call `toInputList()` or stitch history together |
| 22 | +between turns. The TypeScript SDK currently ships with one ready-to-use |
| 23 | +`OpenAIConversationsSession`, and the same `Session` interface lets you bring your |
| 24 | +own storage. For inspiration beyond the OpenAI Conversations API, browse the |
| 25 | +sample session backends under `examples/memory/` (Prisma, file-backed, and more). |
| 26 | + |
| 27 | +> Tip: To run the `OpenAIConversationsSession` examples on this page, set the |
| 28 | +> `OPENAI_API_KEY` environment variable (or provide an `apiKey` when constructing |
| 29 | +> the session) so the SDK can call the Conversations API. |
| 30 | +
|
| 31 | +--- |
| 32 | + |
| 33 | +## Quick start |
| 34 | + |
| 35 | +Use an `OpenAIConversationsSession` (or any other `Session` implementation) to sync memory with the |
| 36 | +[Conversations API](https://platform.openai.com/docs/api-reference/conversations). |
| 37 | + |
| 38 | +<Code |
| 39 | + lang="typescript" |
| 40 | + code={sessionsQuickstart} |
| 41 | + title="Use the Conversations API as session memory" |
| 42 | +/> |
| 43 | + |
| 44 | +When you reuse the same session instance, the agent receives the full conversation |
| 45 | +history before every turn and writes new items back automatically. |
| 46 | + |
| 47 | +Swap `OpenAIConversationsSession` with any other `Session` implementation—no other |
| 48 | +code changes are required. |
| 49 | + |
| 50 | +--- |
| 51 | + |
| 52 | +## How the runner uses sessions |
| 53 | + |
| 54 | +- **Before each run** the runner retrieves the session history, merges it with the |
| 55 | + new turn’s input, and passes the combined list to your agent. |
| 56 | +- **After a non-streaming run** a single call to `session.addItems()` persists both |
| 57 | + the original user input and the model outputs from the latest turn. |
| 58 | +- **For streaming runs** the runner writes the user input up front and appends |
| 59 | + streamed outputs once the turn completes. |
| 60 | +- **When resuming from `RunResult.state`** (for approval flows or other interruptions) |
| 61 | + continue passing the same `session`. The resumed turn is added to memory without |
| 62 | + re-preparing the input. |
| 63 | + |
| 64 | +--- |
| 65 | + |
| 66 | +## Inspecting and editing history |
| 67 | + |
| 68 | +Sessions expose simple CRUD helpers so you can build “undo”, “clear chat”, or audit |
| 69 | +features. |
| 70 | + |
| 71 | +<Code |
| 72 | + lang="typescript" |
| 73 | + code={manageHistory} |
| 74 | + title="Read and edit stored items" |
| 75 | +/> |
| 76 | + |
| 77 | +`session.getItems()` returns the stored `AgentInputItem[]`. Call `popItem()` to |
| 78 | +remove the last entry—useful for user corrections before you rerun the agent. |
| 79 | + |
| 80 | +--- |
| 81 | + |
| 82 | +## Bring your own storage |
| 83 | + |
| 84 | +Implement the `Session` interface to back memory with Redis, DynamoDB, |
| 85 | +SQLite, or another datastore. Only five asynchronous methods are required. |
| 86 | + |
| 87 | +<Code |
| 88 | + lang="typescript" |
| 89 | + code={customSession} |
| 90 | + title="Custom in-memory session implementation" |
| 91 | +/> |
| 92 | + |
| 93 | +Custom sessions let you enforce retention policies, add encryption, or attach |
| 94 | +metadata to each conversation turn before persisting it. |
| 95 | + |
| 96 | +--- |
| 97 | + |
| 98 | +## Control how history and new items merge |
| 99 | + |
| 100 | +When you pass an array of `AgentInputItem`s as the run input, provide a |
| 101 | +`sessionInputCallback` to merge them with stored history deterministically. |
| 102 | +The runner loads the existing history, calls your callback **before the model |
| 103 | +invocation**, and hands the returned array to the model as the turn’s complete |
| 104 | +input. This hook is ideal for trimming old items, deduplicating tool results, or |
| 105 | +highlighting only the context you want the model to see. |
| 106 | + |
| 107 | +<Code |
| 108 | + lang="typescript" |
| 109 | + code={sessionInputCallback} |
| 110 | + title="Truncate history with sessionInputCallback" |
| 111 | +/> |
| 112 | + |
| 113 | +For string inputs the runner can merge history automatically, so you can omit the |
| 114 | +callback. |
| 115 | + |
| 116 | +--- |
| 117 | + |
| 118 | +## Handling approvals and resumable runs |
| 119 | + |
| 120 | +Human-in-the-loop flows often pause a run to wait for approval: |
| 121 | + |
| 122 | +```typescript |
| 123 | +const result = await runner.run(agent, 'Search the itinerary', { |
| 124 | + session, |
| 125 | + stream: true, |
| 126 | +}); |
| 127 | + |
| 128 | +if (result.requiresApproval) { |
| 129 | + // ... collect user feedback, then resume the agent in a later turn |
| 130 | + const continuation = await runner.run(agent, result.state, { session }); |
| 131 | + console.log(continuation.finalOutput); |
| 132 | +} |
| 133 | +``` |
| 134 | + |
| 135 | +Because sessions now work when resuming from a previous `RunState`, the continued |
| 136 | +turn is appended to the same memory record, maintaining a single coherent history |
| 137 | +for the conversation. This keeps human-in-the-loop (HITL) flows fully compatible— |
| 138 | +your approval checkpoints continue to round-trip through `RunState` while the |
| 139 | +session keeps the transcript complete. |
0 commit comments