/**
 * Source-mode-specific switch tools.
 *
 * Each interactive mode gets its own switch tool surface:
 * - switch_from_action_mode
 * - switch_from_plan_mode
 * - switch_from_installation_mode
 *
 * This avoids stale mode-aware descriptions because the tool contract is
 * fixed for the current/source mode and only advertises that mode's valid
 * outgoing transitions.
 */
import { Type } from '@sinclair/typebox';
import { MODE } from '../../mode-names.js';
import { ACTION_SWITCH_MODE, INSTALLATION_SWITCH_MODE, PLAN_SWITCH_MODE } from '../../tool-names.js';
import { APPROVAL } from '../approvals/types.js';
import { getMode } from '../modes/index.js';
import { switchMode } from '../modes/switch-mode.js';
function buildDescription(sourceModeName, allowedTargets) {
    const modeList = allowedTargets.length > 0
        ? allowedTargets
            .map((modeName) => {
            const mode = getMode(modeName);
            return `- **${modeName}**: ${mode?.description ?? ''}`;
        })
            .join('\n')
        : '- none';
    return `Switch to a different agent mode from ${sourceModeName}. Swaps system prompt and active tools while keeping message history.

${modeList}`;
}
function buildModeSchema(allowedTargets) {
    if (allowedTargets.length === 0) {
        return Type.String({
            description: 'No ordinary mode switches are available from this mode.'
        });
    }
    return Type.Union(allowedTargets.map((mode) => Type.Literal(mode)), {
        description: 'The mode to switch to'
    });
}
function buildSchema(sourceModeName, allowedTargets) {
    const reasonDescription = sourceModeName === MODE.PLAN
        ? "Implementation plan for the action handoff. Write in first person from the user's perspective."
        : sourceModeName === MODE.ACTION
            ? "Write the user's actual task or a concise restatement of it from the user's POV."
            : 'Optional context for the mode switch.';
    return Type.Object({
        mode: buildModeSchema(allowedTargets),
        reason: Type.Optional(Type.String({
            description: reasonDescription
        }))
    });
}
function buildLabel(sourceModeName) {
    return `${sourceModeName.charAt(0).toUpperCase()}${sourceModeName.slice(1)} Switch Mode`;
}
async function confirmModeSwitchWithApprovalGate(approval, extCtx, request) {
    const choice = await approval.requestApproval({
        kind: 'switch-mode',
        title: `Switch from ${request.currentMode} to ${request.targetMode}`,
        payload: {
            currentMode: request.currentMode,
            targetMode: request.targetMode,
            reason: request.reason
        },
        alwaysRequireExplicitApproval: true
    }, extCtx);
    return choice === APPROVAL.ACCEPT;
}
function createSourceModeSwitchTool(toolName, sourceModeName, allowedTargets, session, settings, approval) {
    const schema = buildSchema(sourceModeName, allowedTargets);
    return {
        name: toolName,
        label: buildLabel(sourceModeName),
        isReadOnly: false,
        description: buildDescription(sourceModeName, allowedTargets),
        parameters: schema,
        async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
            const parsedParams = params;
            const extCtx = ctx;
            const result = await switchMode(session(), parsedParams.mode, {
                settings,
                reason: parsedParams.reason,
                ctx: extCtx,
                confirm: approval && extCtx
                    ? (request) => confirmModeSwitchWithApprovalGate(approval, extCtx, request)
                    : undefined
            });
            return {
                content: [{ type: 'text', text: result.message }],
                details: null
            };
        }
    };
}
export function createActionSwitchModeTool(session, settings, approval) {
    return createSourceModeSwitchTool(ACTION_SWITCH_MODE, MODE.ACTION, [MODE.PLAN, MODE.INSTALLATION], session, settings, approval);
}
export function createPlanSwitchModeTool(session, settings, approval) {
    return createSourceModeSwitchTool(PLAN_SWITCH_MODE, MODE.PLAN, [MODE.ACTION], session, settings, approval);
}
export function createInstallationSwitchModeTool(session, settings, approval) {
    return createSourceModeSwitchTool(INSTALLATION_SWITCH_MODE, MODE.INSTALLATION, [MODE.ACTION], session, settings, approval);
}
//# sourceMappingURL=switch-mode.js.map