Fork me on GitHub

Session Persistence and Resumption

Save and restore conversation sessions across application restarts.

Prerequisites

Install JBang to run these examples:

# macOS (using Homebrew)
brew install jbangdev/tap/jbang

# Linux/macOS (using curl)
curl -Ls https://sh.jbang.dev | bash -s - app setup

# Windows (using Scoop)
scoop install jbang

Example scenario

You want users to be able to continue a conversation even after closing and reopening your application.

Creating a session with a custom ID

Usage:

jbang PersistingSessions.java

Code:

//DEPS io.github.copilot-community-sdk:copilot-sdk:1.0.9
import com.github.copilot.sdk.*;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;

public class PersistingSessions {
    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient()) {
            client.start().get();

            // Create session with a memorable ID
            var session = client.createSession(
                new SessionConfig()
                    .setSessionId("user-123-conversation")
                    .setModel("gpt-5")
            ).get();

            session.on(AssistantMessageEvent.class, msg -> 
                System.out.println(msg.getData().getContent())
            );

            session.sendAndWait(new MessageOptions()
                .setPrompt("Let's discuss TypeScript generics")).get();

            // Session ID is preserved
            System.out.println("Session ID: " + session.getSessionId());

            // Close session but keep data on disk
            session.close();
        }
    }
}

Resuming a session

public class ResumeSession {
    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient()) {
            client.start().get();

            // Resume the previous session
            var session = client.resumeSession("user-123-conversation").get();

            session.on(AssistantMessageEvent.class, msg -> 
                System.out.println(msg.getData().getContent())
            );

            // Previous context is restored
            session.sendAndWait(new MessageOptions()
                .setPrompt("What were we discussing?")).get();

            session.close();
        }
    }
}

Listing available sessions

public class ListSessions {
    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient()) {
            client.start().get();

            var sessions = client.listSessions().get();
            for (var sessionInfo : sessions) {
                System.out.println("Session: " + sessionInfo.getSessionId());
            }
        }
    }
}

Deleting a session permanently

public class DeleteSession {
    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient()) {
            client.start().get();

            // Remove session and all its data from disk
            client.deleteSession("user-123-conversation").get();
            System.out.println("Session deleted");
        }
    }
}

Getting session history

//DEPS io.github.copilot-community-sdk:copilot-sdk:1.0.9
import com.github.copilot.sdk.*;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;

public class SessionHistory {
    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient()) {
            client.start().get();

            var session = client.resumeSession("user-123-conversation").get();

            var messages = session.getMessages().get();
            for (var event : messages) {
                // Print different event types appropriately
                if (event instanceof AssistantMessageEvent msg) {
                    System.out.printf("[assistant] %s%n", msg.getData().getContent());
                } else if (event instanceof UserMessageEvent userMsg) {
                    System.out.printf("[user] %s%n", userMsg.getData().content());
                } else {
                    System.out.printf("[%s]%n", event.getType());
                }
            }

            session.close();
        }
    }
}

Complete example with session management

//DEPS io.github.copilot-community-sdk:copilot-sdk:1.0.9
import java.util.Scanner;

public class SessionManager {
    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient();
             var scanner = new Scanner(System.in)) {
            
            client.start().get();

            System.out.println("Session Manager");
            System.out.println("1. Create new session");
            System.out.println("2. Resume existing session");
            System.out.println("3. List sessions");
            System.out.print("Choose an option: ");

            int choice = scanner.nextInt();
            scanner.nextLine(); // consume newline

            CopilotSession session = null;

            switch (choice) {
                case 1:
                    System.out.print("Enter session ID: ");
                    String sessionId = scanner.nextLine();
                    session = client.createSession(
                        new SessionConfig()
                            .setSessionId(sessionId)
                            .setModel("gpt-5")
                    ).get();
                    System.out.println("Created session: " + sessionId);
                    break;

                case 2:
                    System.out.print("Enter session ID to resume: ");
                    String resumeId = scanner.nextLine();
                    try {
                        session = client.resumeSession(resumeId).get();
                        System.out.println("Resumed session: " + resumeId);
                    } catch (Exception ex) {
                        System.err.println("Failed to resume session: " + ex.getMessage());
                        return;
                    }
                    break;

                case 3:
                    var sessions = client.listSessions().get();
                    System.out.println("\nAvailable sessions:");
                    for (var s : sessions) {
                        System.out.println("  - " + s.getSessionId());
                    }
                    return;

                default:
                    System.out.println("Invalid choice");
                    return;
            }

            if (session != null) {
                session.on(AssistantMessageEvent.class, msg -> 
                    System.out.println("\nCopilot: " + msg.getData().getContent())
                );

                // Interactive conversation loop
                System.out.println("\nStart chatting (type 'exit' to quit):");
                while (true) {
                    System.out.print("\nYou: ");
                    String input = scanner.nextLine();
                    
                    if (input.equalsIgnoreCase("exit")) {
                        break;
                    }

                    session.send(new MessageOptions().setPrompt(input));
                    Thread.sleep(2000); // Give time for response
                }

                session.close();
            }
        }
    }
}

Checking if a session exists

public class CheckSession {
    public static boolean sessionExists(CopilotClient client, String sessionId) {
        try {
            var sessions = client.listSessions().get();
            return sessions.stream()
                .anyMatch(s -> s.getSessionId().equals(sessionId));
        } catch (Exception ex) {
            return false;
        }
    }

    public static void main(String[] args) throws Exception {
        try (var client = new CopilotClient()) {
            client.start().get();

            String sessionId = "user-123-conversation";
            
            if (sessionExists(client, sessionId)) {
                System.out.println("Session exists, resuming...");
                var session = client.resumeSession(sessionId).get();
                // ... use session ...
                session.close();
            } else {
                System.out.println("Session doesn't exist, creating new one...");
                var session = client.createSession(
                    new SessionConfig().setSessionId(sessionId).setModel("gpt-5")
                ).get();
                // ... use session ...
                session.close();
            }
        }
    }
}

Best practices

  1. Use meaningful session IDs: Include user ID or context in the session ID (e.g., “user-123-chat”, “task-456-review”)
  2. Handle missing sessions: Check if a session exists before resuming
  3. Clean up old sessions: Periodically delete sessions that are no longer needed
  4. Error handling: Always wrap resume operations in try-catch blocks
  5. Workspace awareness: Sessions are tied to workspace paths, ensure consistency