diff --git a/docs/guides/session-persistence.md b/docs/guides/session-persistence.md index 527f5ecc7..dec91d5fb 100644 --- a/docs/guides/session-persistence.md +++ b/docs/guides/session-persistence.md @@ -325,16 +325,16 @@ async function cleanupExpiredSessions(maxAgeMs: number) { await cleanupExpiredSessions(24 * 60 * 60 * 1000); ``` -### Explicit Session Destruction +### Closing a Session (`destroy`) -When a task completes, destroy the session explicitly rather than waiting for timeouts: +When a task completes, close the session explicitly rather than waiting for timeouts. This releases in-memory resources but **preserves session data on disk**, so the session can still be resumed later: ```typescript try { // Do work... await session.sendAndWait({ prompt: "Complete the task" }); - // Task complete - clean up + // Task complete — release in-memory resources (session can be resumed later) await session.destroy(); } catch (error) { // Clean up even on error @@ -343,6 +343,17 @@ try { } ``` +### Permanently Deleting a Session (`deleteSession`) + +To permanently remove a session and all its data from disk (conversation history, planning state, artifacts), use `deleteSession`. This is irreversible — the session **cannot** be resumed after deletion: + +```typescript +// Permanently remove session data +await client.deleteSession("user-123-task-456"); +``` + +> **`destroy()` vs `deleteSession()`:** `destroy()` releases in-memory resources but keeps session data on disk for later resumption. `deleteSession()` permanently removes everything, including files on disk. + ## Automatic Cleanup: Idle Timeout The CLI has a built-in 30-minute idle timeout. Sessions without activity are automatically cleaned up: @@ -526,8 +537,8 @@ await withSessionLock("user-123-task-456", async () => { | **Resume session** | `client.resumeSession(sessionId)` | | **BYOK resume** | Re-provide `provider` config | | **List sessions** | `client.listSessions(filter?)` | -| **Delete session** | `client.deleteSession(sessionId)` | -| **Destroy active session** | `session.destroy()` | +| **Close active session** | `session.destroy()` — releases in-memory resources; session data on disk is preserved for resumption | +| **Delete session permanently** | `client.deleteSession(sessionId)` — permanently removes all session data from disk; cannot be resumed | | **Containerized deployment** | Mount `~/.copilot/session-state/` to persistent storage | ## Next Steps diff --git a/dotnet/src/Client.cs b/dotnet/src/Client.cs index 1f3a7fb43..40e153260 100644 --- a/dotnet/src/Client.cs +++ b/dotnet/src/Client.cs @@ -210,18 +210,23 @@ async Task StartCoreAsync(CancellationToken ct) } /// - /// Disconnects from the Copilot server and stops all active sessions. + /// Disconnects from the Copilot server and closes all active sessions. /// /// A representing the asynchronous operation. /// /// /// This method performs graceful cleanup: /// - /// Destroys all active sessions + /// Closes all active sessions (releases in-memory resources) /// Closes the JSON-RPC connection /// Terminates the CLI server process (if spawned by this client) /// /// + /// + /// Note: session data on disk is preserved, so sessions can be resumed later. + /// To permanently remove session data before stopping, call + /// for each session first. + /// /// /// Thrown when multiple errors occur during cleanup. /// @@ -655,15 +660,17 @@ public async Task> ListModelsAsync(CancellationToken cancellatio } /// - /// Deletes a Copilot session by its ID. + /// Permanently deletes a session and all its data from disk, including + /// conversation history, planning state, and artifacts. /// /// The ID of the session to delete. /// A that can be used to cancel the operation. /// A task that represents the asynchronous delete operation. /// Thrown when the session does not exist or deletion fails. /// - /// This permanently removes the session and all its conversation history. - /// The session cannot be resumed after deletion. + /// Unlike , which only releases in-memory + /// resources and preserves session data for later resumption, this method is + /// irreversible. The session cannot be resumed after deletion. /// /// /// diff --git a/dotnet/src/Session.cs b/dotnet/src/Session.cs index 923b193cc..02bb276dc 100644 --- a/dotnet/src/Session.cs +++ b/dotnet/src/Session.cs @@ -541,22 +541,25 @@ await InvokeRpcAsync( } /// - /// Disposes the and releases all associated resources. + /// Closes this session and releases all in-memory resources (event handlers, + /// tool handlers, permission handlers). /// /// A task representing the dispose operation. /// /// - /// After calling this method, the session can no longer be used. All event handlers - /// and tool handlers are cleared. + /// Session state on disk (conversation history, planning state, artifacts) is + /// preserved, so the conversation can be resumed later by calling + /// with the session ID. To + /// permanently remove all session data including files on disk, use + /// instead. /// /// - /// To continue the conversation, use - /// with the session ID. + /// After calling this method, the session object can no longer be used. /// /// /// /// - /// // Using 'await using' for automatic disposal + /// // Using 'await using' for automatic disposal — session can still be resumed later /// await using var session = await client.CreateSessionAsync(new() { OnPermissionRequest = PermissionHandler.ApproveAll }); /// /// // Or manually dispose diff --git a/go/client.go b/go/client.go index c88a68ac3..f140127b6 100644 --- a/go/client.go +++ b/go/client.go @@ -293,10 +293,14 @@ func (c *Client) Start(ctx context.Context) error { // Stop stops the CLI server and closes all active sessions. // // This method performs graceful cleanup: -// 1. Destroys all active sessions +// 1. Closes all active sessions (releases in-memory resources) // 2. Closes the JSON-RPC connection // 3. Terminates the CLI server process (if spawned by this client) // +// Note: session data on disk is preserved, so sessions can be resumed later. +// To permanently remove session data before stopping, call [Client.DeleteSession] +// for each session first. +// // Returns an error that aggregates all errors encountered during cleanup. // // Example: @@ -685,8 +689,11 @@ func (c *Client) ListSessions(ctx context.Context, filter *SessionListFilter) ([ return response.Sessions, nil } -// DeleteSession permanently deletes a session and all its conversation history. +// DeleteSession permanently deletes a session and all its data from disk, +// including conversation history, planning state, and artifacts. // +// Unlike [Session.Destroy], which only releases in-memory resources and +// preserves session data for later resumption, DeleteSession is irreversible. // The session cannot be resumed after deletion. If the session is in the local // sessions map, it will be removed. // diff --git a/go/session.go b/go/session.go index 12d1b1afa..561e566d1 100644 --- a/go/session.go +++ b/go/session.go @@ -511,17 +511,21 @@ func (s *Session) GetMessages(ctx context.Context) ([]SessionEvent, error) { return response.Events, nil } -// Destroy destroys this session and releases all associated resources. +// Destroy closes this session and releases all in-memory resources (event +// handlers, tool handlers, permission handlers). // -// After calling this method, the session can no longer be used. All event -// handlers and tool handlers are cleared. To continue the conversation, -// use [Client.ResumeSession] with the session ID. +// Session state on disk (conversation history, planning state, artifacts) is +// preserved, so the conversation can be resumed later by calling +// [Client.ResumeSession] with the session ID. To permanently remove all +// session data including files on disk, use [Client.DeleteSession] instead. +// +// After calling this method, the session object can no longer be used. // // Returns an error if the connection fails. // // Example: // -// // Clean up when done +// // Clean up when done — session can still be resumed later // if err := session.Destroy(); err != nil { // log.Printf("Failed to destroy session: %v", err) // } diff --git a/nodejs/src/client.ts b/nodejs/src/client.ts index 6d841c7cc..c8c81dc74 100644 --- a/nodejs/src/client.ts +++ b/nodejs/src/client.ts @@ -307,10 +307,14 @@ export class CopilotClient { * Stops the CLI server and closes all active sessions. * * This method performs graceful cleanup: - * 1. Destroys all active sessions with retry logic + * 1. Closes all active sessions (releases in-memory resources) * 2. Closes the JSON-RPC connection * 3. Terminates the CLI server process (if spawned by this client) * + * Note: session data on disk is preserved, so sessions can be resumed later. + * To permanently remove session data before stopping, call + * {@link deleteSession} for each session first. + * * @returns A promise that resolves with an array of errors encountered during cleanup. * An empty array indicates all cleanup succeeded. * @@ -823,10 +827,12 @@ export class CopilotClient { } /** - * Deletes a session and its data from disk. + * Permanently deletes a session and all its data from disk, including + * conversation history, planning state, and artifacts. * - * This permanently removes the session and all its conversation history. - * The session cannot be resumed after deletion. + * Unlike {@link CopilotSession.destroy}, which only releases in-memory + * resources and preserves session data for later resumption, this method + * is irreversible. The session cannot be resumed after deletion. * * @param sessionId - The ID of the session to delete * @returns A promise that resolves when the session is deleted diff --git a/nodejs/src/session.ts b/nodejs/src/session.ts index 04525d2bb..6e32ee5f9 100644 --- a/nodejs/src/session.ts +++ b/nodejs/src/session.ts @@ -499,18 +499,23 @@ export class CopilotSession { } /** - * Destroys this session and releases all associated resources. + * Closes this session and releases all in-memory resources (event handlers, + * tool handlers, permission handlers). * - * After calling this method, the session can no longer be used. All event - * handlers and tool handlers are cleared. To continue the conversation, - * use {@link CopilotClient.resumeSession} with the session ID. + * Session state on disk (conversation history, planning state, artifacts) is + * preserved, so the conversation can be resumed later by calling + * {@link CopilotClient.resumeSession} with the session ID. To permanently + * remove all session data including files on disk, use + * {@link CopilotClient.deleteSession} instead. * - * @returns A promise that resolves when the session is destroyed + * After calling this method, the session object can no longer be used. + * + * @returns A promise that resolves when the session is closed * @throws Error if the connection fails * * @example * ```typescript - * // Clean up when done + * // Clean up when done — session can still be resumed later * await session.destroy(); * ``` */ diff --git a/python/copilot/client.py b/python/copilot/client.py index c25e68096..2d50c73e5 100644 --- a/python/copilot/client.py +++ b/python/copilot/client.py @@ -320,10 +320,14 @@ async def stop(self) -> list["StopError"]: Stop the CLI server and close all active sessions. This method performs graceful cleanup: - 1. Destroys all active sessions + 1. Closes all active sessions (releases in-memory resources) 2. Closes the JSON-RPC connection 3. Terminates the CLI server process (if spawned by this client) + Note: session data on disk is preserved, so sessions can be resumed + later. To permanently remove session data before stopping, call + :meth:`delete_session` for each session first. + Returns: A list of StopError objects containing error messages that occurred during cleanup. An empty list indicates all cleanup succeeded. @@ -928,10 +932,12 @@ async def list_sessions( async def delete_session(self, session_id: str) -> None: """ - Delete a session permanently. + Permanently delete a session and all its data from disk, including + conversation history, planning state, and artifacts. - This permanently removes the session and all its conversation history. - The session cannot be resumed after deletion. + Unlike :meth:`CopilotSession.destroy`, which only releases in-memory + resources and preserves session data for later resumption, this method + is irreversible. The session cannot be resumed after deletion. Args: session_id: The ID of the session to delete. diff --git a/python/copilot/session.py b/python/copilot/session.py index a02dcf1e9..72c085304 100644 --- a/python/copilot/session.py +++ b/python/copilot/session.py @@ -476,17 +476,22 @@ async def get_messages(self) -> list[SessionEvent]: async def destroy(self) -> None: """ - Destroy this session and release all associated resources. + Close this session and release all in-memory resources (event handlers, + tool handlers, permission handlers). - After calling this method, the session can no longer be used. All event - handlers and tool handlers are cleared. To continue the conversation, - use :meth:`CopilotClient.resume_session` with the session ID. + Session state on disk (conversation history, planning state, artifacts) + is preserved, so the conversation can be resumed later by calling + :meth:`CopilotClient.resume_session` with the session ID. To + permanently remove all session data including files on disk, use + :meth:`CopilotClient.delete_session` instead. + + After calling this method, the session object can no longer be used. Raises: Exception: If the connection fails. Example: - >>> # Clean up when done + >>> # Clean up when done — session can still be resumed later >>> await session.destroy() """ await self._client.request("session.destroy", {"sessionId": self.session_id})