/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. *--------------------------------------------------------------------------------------------*/ package com.github.copilot.sdk; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import com.github.copilot.sdk.json.CopilotClientOptions; import com.github.copilot.sdk.json.CreateSessionResponse; import com.github.copilot.sdk.json.DeleteSessionResponse; import com.github.copilot.sdk.json.GetAuthStatusResponse; import com.github.copilot.sdk.json.GetLastSessionIdResponse; import com.github.copilot.sdk.json.GetModelsResponse; import com.github.copilot.sdk.json.GetStatusResponse; import com.github.copilot.sdk.json.ListSessionsResponse; import com.github.copilot.sdk.json.ModelInfo; import com.github.copilot.sdk.json.PingResponse; import com.github.copilot.sdk.json.ResumeSessionConfig; import com.github.copilot.sdk.json.ResumeSessionResponse; import com.github.copilot.sdk.json.SessionConfig; import com.github.copilot.sdk.json.SessionLifecycleHandler; import com.github.copilot.sdk.json.SessionMetadata; /** * Provides a client for interacting with the Copilot CLI server. *
* The CopilotClient manages the connection to the Copilot CLI server and * provides methods to create and manage conversation sessions. It can either * spawn a CLI server process or connect to an existing server. *
* Example usage: * *
{@code
* try (var client = new CopilotClient()) {
* client.start().get();
*
* var session = client.createSession(new SessionConfig().setModel("gpt-5")).get();
*
* session.on(AssistantMessageEvent.class, msg -> {
* System.out.println(msg.getData().getContent());
* });
*
* session.send(new MessageOptions().setPrompt("Hello!")).get();
* }
* }
*
* @since 1.0.0
*/
public final class CopilotClient implements AutoCloseable {
private static final Logger LOG = Logger.getLogger(CopilotClient.class.getName());
private final CopilotClientOptions options;
private final CliServerManager serverManager;
private final LifecycleEventManager lifecycleManager = new LifecycleEventManager();
private final Map
* The session maintains conversation state and can be used to send messages and
* receive responses. Remember to close the session when done.
*
* @param config
* configuration for the session (model, tools, etc.)
* @return a future that resolves with the created CopilotSession
* @see #createSession()
* @see SessionConfig
*/
public CompletableFuture
* This restores a previously saved session, allowing you to continue a
* conversation. The session's history is preserved.
*
* @param sessionId
* the ID of the session to resume
* @param config
* configuration for the resumed session
* @return a future that resolves with the resumed CopilotSession
* @see #resumeSession(String)
* @see #listSessions()
* @see #getLastSessionId()
*/
public CompletableFuture
* This can be used to verify that the server is responsive and to check the
* protocol version.
*
* @param message
* an optional message to echo back
* @return a future that resolves with the ping response
* @see PingResponse
*/
public CompletableFuture
* Results are cached after the first successful call to avoid rate limiting.
* The cache is cleared when the client disconnects.
*
* @return a future that resolves with a list of available models
* @see ModelInfo
*/
public CompletableFuture
* This is useful for resuming the last conversation without needing to list all
* sessions.
*
* @return a future that resolves with the last session ID, or {@code null} if
* no sessions exist
* @see #resumeSession(String)
*/
public CompletableFuture
* This permanently removes the session and its conversation history.
*
* @param sessionId
* the ID of the session to delete
* @return a future that completes when the session is deleted
* @throws RuntimeException
* if the deletion fails
*/
public CompletableFuture
* Returns metadata about all sessions that can be resumed, including their IDs,
* start times, and summaries.
*
* @return a future that resolves with a list of session metadata
* @see SessionMetadata
* @see #resumeSession(String)
*/
public CompletableFuture
* This is only available when connecting to a server running in TUI+server mode
* (--ui-server).
*
* @return a future that resolves with the session ID, or null if no foreground
* session is set
*/
public CompletableFuture
* This is only available when connecting to a server running in TUI+server mode
* (--ui-server).
*
* @param sessionId
* the ID of the session to display in the TUI
* @return a future that completes when the operation is done
* @throws RuntimeException
* if the operation fails
*/
public CompletableFuture
* Lifecycle events are emitted when sessions are created, deleted, updated, or
* change foreground/background state (in TUI+server mode).
*
* @param handler
* a callback that receives lifecycle events
* @return an AutoCloseable that, when closed, unsubscribes the handler
*/
public AutoCloseable onLifecycle(SessionLifecycleHandler handler) {
return lifecycleManager.subscribe(handler);
}
/**
* Subscribes to a specific session lifecycle event type.
*
* @param eventType
* the event type to listen for (use
* {@link com.github.copilot.sdk.json.SessionLifecycleEventTypes}
* constants)
* @param handler
* a callback that receives events of the specified type
* @return an AutoCloseable that, when closed, unsubscribes the handler
*/
public AutoCloseable onLifecycle(String eventType, SessionLifecycleHandler handler) {
return lifecycleManager.subscribe(eventType, handler);
}
private CompletableFuture> listModels() {
// Check cache first
List
> listSessions() {
return ensureConnected()
.thenCompose(connection -> connection.rpc.invoke("session.list", Map.of(), ListSessionsResponse.class)
.thenApply(ListSessionsResponse::getSessions));
}
/**
* Gets the ID of the session currently displayed in the TUI.
*