/**
 * Prompt pipeline helpers extracted from AgentSession.
 *
 * Pure functions for parsing and normalizing user input before it reaches
 * the agent: extension command dispatch, content normalization, and
 * message content building. No session state — all dependencies are
 * passed as arguments.
 */
// ============================================================================
// Extension command helpers
// ============================================================================
/**
 * Try to execute an extension command. Returns true if the command was
 * found and executed (even if execution threw — errors are emitted via
 * the runner's error listener, not re-thrown).
 *
 * Expects `text` to start with `/`.
 */
export async function tryExtensionCommand(text, extensionRunner) {
    if (!extensionRunner)
        return false;
    // Parse command name and args
    const spaceIndex = text.indexOf(' ');
    const commandName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);
    const args = spaceIndex === -1 ? '' : text.slice(spaceIndex + 1);
    const command = extensionRunner.getCommand(commandName);
    if (!command)
        return false;
    // Get command context from extension runner (includes session control methods)
    const ctx = extensionRunner.createCommandContext();
    try {
        await command.handler(args, ctx);
        return true;
    }
    catch (err) {
        // Emit error via extension runner
        extensionRunner.emitError({
            extensionPath: `command:${commandName}`,
            event: 'command',
            error: err instanceof Error ? err.message : String(err)
        });
        return true;
    }
}
/**
 * Throw if `text` is a registered extension command.
 *
 * Used by steer/followUp to reject extension commands that cannot be
 * queued mid-stream. Expects `text` to start with `/`.
 */
export function assertNotExtensionCommand(text, extensionRunner) {
    if (!extensionRunner)
        return;
    const spaceIndex = text.indexOf(' ');
    const commandName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);
    const command = extensionRunner.getCommand(commandName);
    if (command) {
        throw new Error(`Extension command "/${commandName}" cannot be queued. Use prompt() or execute the command when not streaming.`);
    }
}
// ============================================================================
// Content helpers
// ============================================================================
/**
 * Build the content array for a user message from text and optional images.
 * Shared by _queueSteer and _queueFollowUp in AgentSession.
 */
export function buildMessageContent(text, images) {
    const content = [{ type: 'text', text }];
    if (images) {
        content.push(...images);
    }
    return content;
}
/**
 * Normalize user-facing content (string or content-part array) into a
 * plain text string and optional image array.
 *
 * Used by `sendUserMessage` to unify the two input shapes before
 * handing off to `prompt()`.
 */
export function normalizeUserContent(content) {
    if (typeof content === 'string') {
        return { text: content };
    }
    const textParts = [];
    const images = [];
    for (const part of content) {
        if (part.type === 'text') {
            textParts.push(part.text);
        }
        else {
            images.push(part);
        }
    }
    return {
        text: textParts.join('\n'),
        images: images.length > 0 ? images : undefined
    };
}
//# sourceMappingURL=prompt-pipeline.js.map