Agent stores configuration; a Session stores the conversation identity. Repeated agent.run() calls start independent conversations. Repeated session.send() calls continue one conversation.
Send a follow-up and resume
Use the TypeScript example setup. This complete example saves a fact, closes its local handle, and resumes the same conversation while its owning runtime remains alive.agent owns the runtime throughout this example. Calling agent.close() removes its isolated temporary state; the recorded ID alone cannot recover that conversation afterward.
session.send() returns a ResultMessage. Check subtype === "success"; unlike Agent.run()’s result, it has no isError convenience field. text can be absent on a tool-only or unsuccessful result.
Work with a live session
A session accepts only one active query at a time. Await a send or finish/cancel a stream before starting the next one. Use separate sessions for concurrent conversations. A resumed handle’s live usage counters begin at zero; they are not the lifetime accounting history of the persisted transcript.
In v2,
Session.send() does not accept an options argument, and Session.stream() options only select partial messages. Use session.interrupt() to cancel an active Session turn. External AbortSignal options belong to Agent.run() and Agent.stream().
Fork a conversation
A fork copies conversation history into a new session so you can explore another direction without appending to the original. The optionalmessageId selects the boundary; omit it to fork the current transcript.
Inside the owning Agent’s try block, after a session has been created, you can use:
Resume with the intended policy
agent.resume(id) reconnects to a session on that Agent’s runtime. Explicit constructor options override stored runtime settings; unspecified options preserve them. Supply custom tool, hook, and permission callbacks again when attaching from another application process.
A fresh dedicated isolated runtime cannot see sessions from a different runtime. Keep the original owner alive, share an explicitly owned client, or connect to a persistent remote runtime. Resume/fork cannot change the original working directory. If you need per-session directories and later resume, pass cwd to createSession() rather than to the Agent constructor.
With the lower-level client, client.sessions.resume(id, { runtimeConfig, title, permission }) applies explicit overrides before attachment. Empty collections can clear prior values, such as hooks: {}, sdkMcpServers: [], or agents: {}; canUseTool: false removes a callback registration. An active local handle cannot have its runtime configuration replaced underneath it.
Understand what survives cleanup
For durable conversations, choose persistent runtime storage deliberately. Preserving scratch files for debugging does not automatically reconnect a future Agent to that database.
For explicit retention management, obtain the client with
await agent.client() and use client.sessions.list() or client.sessions.delete(id). Delete only conversations you intend to remove. deleteSessionsOnClose: true deletes sessions created or forked by that Agent; resumed sessions are retained. The session-memory project demonstrates ownership with an explicitly created client.