SessionRequestBuilder.java

/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *--------------------------------------------------------------------------------------------*/

package com.github.copilot.sdk;

import com.github.copilot.sdk.json.CreateSessionRequest;
import com.github.copilot.sdk.json.ResumeSessionConfig;
import com.github.copilot.sdk.json.ResumeSessionRequest;
import com.github.copilot.sdk.json.SessionConfig;

/**
 * Builds JSON-RPC request objects from session configuration.
 * <p>
 * This class handles the conversion of SDK configuration objects
 * ({@link SessionConfig}, {@link ResumeSessionConfig}) to JSON-RPC request
 * objects for session creation and resumption.
 */
final class SessionRequestBuilder {

    private SessionRequestBuilder() {
        // Utility class
    }

    /**
     * Builds a CreateSessionRequest from the given configuration.
     *
     * @param config
     *            the session configuration (may be null)
     * @param sessionId
     *            the pre-generated session ID to use
     * @return the built request object
     */
    static CreateSessionRequest buildCreateRequest(SessionConfig config, String sessionId) {
        var request = new CreateSessionRequest();
        // Always request permission callbacks to enable deny-by-default behavior
        request.setRequestPermission(true);
        // Always send envValueMode=direct for MCP servers
        request.setEnvValueMode("direct");
        request.setSessionId(sessionId);
        if (config == null) {
            return request;
        }

        request.setModel(config.getModel());
        request.setClientName(config.getClientName());
        request.setReasoningEffort(config.getReasoningEffort());
        request.setTools(config.getTools());
        request.setSystemMessage(config.getSystemMessage());
        request.setAvailableTools(config.getAvailableTools());
        request.setExcludedTools(config.getExcludedTools());
        request.setProvider(config.getProvider());
        request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);
        request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);
        request.setWorkingDirectory(config.getWorkingDirectory());
        request.setStreaming(config.isStreaming() ? true : null);
        request.setMcpServers(config.getMcpServers());
        request.setCustomAgents(config.getCustomAgents());
        request.setAgent(config.getAgent());
        request.setInfiniteSessions(config.getInfiniteSessions());
        request.setSkillDirectories(config.getSkillDirectories());
        request.setDisabledSkills(config.getDisabledSkills());
        request.setConfigDir(config.getConfigDir());

        return request;
    }

    /**
     * Builds a CreateSessionRequest from the given configuration.
     *
     * @param config
     *            the session configuration (may be null)
     * @return the built request object
     * @deprecated Use {@link #buildCreateRequest(SessionConfig, String)} instead.
     */
    @Deprecated
    static CreateSessionRequest buildCreateRequest(SessionConfig config) {
        String sessionId = (config != null && config.getSessionId() != null)
                ? config.getSessionId()
                : java.util.UUID.randomUUID().toString();
        return buildCreateRequest(config, sessionId);
    }

    /**
     * Builds a ResumeSessionRequest from the given session ID and configuration.
     *
     * @param sessionId
     *            the ID of the session to resume
     * @param config
     *            the resume configuration (may be null)
     * @return the built request object
     */
    static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionConfig config) {
        var request = new ResumeSessionRequest();
        request.setSessionId(sessionId);
        // Always request permission callbacks to enable deny-by-default behavior
        request.setRequestPermission(true);
        // Always send envValueMode=direct for MCP servers
        request.setEnvValueMode("direct");

        if (config == null) {
            return request;
        }

        request.setModel(config.getModel());
        request.setClientName(config.getClientName());
        request.setReasoningEffort(config.getReasoningEffort());
        request.setTools(config.getTools());
        request.setSystemMessage(config.getSystemMessage());
        request.setAvailableTools(config.getAvailableTools());
        request.setExcludedTools(config.getExcludedTools());
        request.setProvider(config.getProvider());
        request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);
        request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);
        request.setWorkingDirectory(config.getWorkingDirectory());
        request.setConfigDir(config.getConfigDir());
        request.setDisableResume(config.isDisableResume() ? true : null);
        request.setStreaming(config.isStreaming() ? true : null);
        request.setMcpServers(config.getMcpServers());
        request.setCustomAgents(config.getCustomAgents());
        request.setAgent(config.getAgent());
        request.setSkillDirectories(config.getSkillDirectories());
        request.setDisabledSkills(config.getDisabledSkills());
        request.setInfiniteSessions(config.getInfiniteSessions());

        return request;
    }

    /**
     * Configures a session with handlers from the given config.
     *
     * @param session
     *            the session to configure
     * @param config
     *            the session configuration
     */
    static void configureSession(CopilotSession session, SessionConfig config) {
        if (config == null) {
            return;
        }

        if (config.getTools() != null) {
            session.registerTools(config.getTools());
        }
        if (config.getOnPermissionRequest() != null) {
            session.registerPermissionHandler(config.getOnPermissionRequest());
        }
        if (config.getOnUserInputRequest() != null) {
            session.registerUserInputHandler(config.getOnUserInputRequest());
        }
        if (config.getHooks() != null) {
            session.registerHooks(config.getHooks());
        }
        if (config.getOnEvent() != null) {
            session.on(config.getOnEvent());
        }
    }

    /**
     * Configures a resumed session with handlers from the given config.
     *
     * @param session
     *            the session to configure
     * @param config
     *            the resume session configuration
     */
    static void configureSession(CopilotSession session, ResumeSessionConfig config) {
        if (config == null) {
            return;
        }

        if (config.getTools() != null) {
            session.registerTools(config.getTools());
        }
        if (config.getOnPermissionRequest() != null) {
            session.registerPermissionHandler(config.getOnPermissionRequest());
        }
        if (config.getOnUserInputRequest() != null) {
            session.registerUserInputHandler(config.getOnUserInputRequest());
        }
        if (config.getHooks() != null) {
            session.registerHooks(config.getHooks());
        }
        if (config.getOnEvent() != null) {
            session.on(config.getOnEvent());
        }
    }
}