/**
 * Runtime prompt builders extracted from agent-runtime.ts.
 *
 * These functions produce prompt strings for provider decision turns,
 * tool follow-ups, repair guidance, and budget finalization.  They are
 * pure functions with no runtime state dependencies.
 */
import { splitRequiredToolGroups, } from "../runtime/provider-turn/tool-constraint-types.js";
// ---------------------------------------------------------------------------
// Internal constants
// ---------------------------------------------------------------------------
const DELEGATE_TASKS_TOOL_NAME = "delegate_tasks";
// ---------------------------------------------------------------------------
// Tool follow-up prompt
// ---------------------------------------------------------------------------
export function buildToolFollowUpSystemPrompt(toolCalls) {
    const extraInstructions = Array.from(new Set(toolCalls
        .map((toolCall) => toolCall.toolName === DELEGATE_TASKS_TOOL_NAME
        ? "The delegate_tasks result already contains the child findings. Child threads did not write scratch or workspace files. Do not call read-scratch for invented child report names."
        : toolCall.toolName === "workspace-files"
            ? "Treat the workspace-files output as one page of path evidence. Reuse returned paths exactly when continuing file grounding."
            : toolCall.toolName === "read-scratch"
                ? "Use the scratch state to avoid re-reading or re-reviewing files you already processed."
                : undefined)
        .filter(Boolean)));
    const resolvedPathInstruction = buildToolFollowUpResolvedPathInstruction(toolCalls);
    const transportLines = [
        "If you need another step, request the relevant tool directly using native function calling.",
        "Do not emit raw tool-call markup, XML-like arg tags, or JSON control payloads in assistant text.",
    ];
    const lines = [
        "You have just received structured tool results for the latest tool batch.",
        ...transportLines,
        ...(extraInstructions.length > 0 ? [extraInstructions.join(" ")] : []),
        ...(resolvedPathInstruction ? [resolvedPathInstruction] : []),
        "Do not mention internal tool-call markup, shell syntax, or chain-of-thought traces in the final answer.",
    ];
    return lines.join(" ");
}
function buildToolFollowUpResolvedPathInstruction(toolCalls) {
    const targets = collectToolFollowUpResolvedWorkspacePaths(toolCalls);
    if (targets.length === 0) {
        return undefined;
    }
    const preview = targets.slice(0, 5);
    const remaining = targets.length - preview.length;
    return `Latest tool batch resolved these workspace paths: ${preview.join(", ")}${remaining > 0 ? `, and ${remaining} more` : ""}. Treat adjacent or rewritten paths as unverified until a tool result confirms them.`;
}
function collectToolFollowUpResolvedWorkspacePaths(toolCalls) {
    const resolvedPaths = new Set();
    for (const toolCall of toolCalls) {
        for (const path of extractResolvedWorkspacePathsFromToolInput(toolCall.toolName, toolCall.toolInput)) {
            resolvedPaths.add(path);
        }
    }
    return [...resolvedPaths];
}
function extractResolvedWorkspacePathsFromToolInput(toolName, input) {
    switch (toolName) {
        case "read-file":
            return readFileToolInputPaths(input);
        default:
            return [];
    }
}
function readFileToolInputPaths(input) {
    if (!input || typeof input !== "object" || Array.isArray(input)) {
        return [];
    }
    const value = input.path;
    if (typeof value === "string") {
        const normalized = value.trim();
        return normalized ? [normalized] : [];
    }
    if (!Array.isArray(value)) {
        return [];
    }
    return value
        .filter((candidate) => typeof candidate === "string")
        .map((candidate) => candidate.trim())
        .filter(Boolean);
}
// ---------------------------------------------------------------------------
// Workspace context prompt
// ---------------------------------------------------------------------------
export function buildWorkspaceContextSystemPrompt(cwd) {
    return [
        `Current workspace root: ${cwd}`,
        "Shell commands already start in this workspace root. Do not prefix repository inspection commands with guessed sandbox directories such as /home/user, /workspace, or /app.",
        "Use workspace-relative paths, or the shell cwd field for a real subdirectory inside the workspace.",
    ].join("\n");
}
// ---------------------------------------------------------------------------
// Required tool prompts
// ---------------------------------------------------------------------------
function formatToolNames(toolNames, conjunction) {
    if (toolNames.length === 0) {
        return "(none)";
    }
    if (toolNames.length === 1) {
        return toolNames[0] ?? "(none)";
    }
    if (toolNames.length === 2) {
        return `${toolNames[0]} ${conjunction} ${toolNames[1]}`;
    }
    return `${toolNames.slice(0, -1).join(", ")}, ${conjunction} ${toolNames.at(-1)}`;
}
function formatRequiredToolNames(constraint) {
    const { requiredAllToolNames, requiredAnyToolGroups } = splitRequiredToolGroups(constraint);
    if (requiredAnyToolGroups.length > 0) {
        const wrapAnyGroup = requiredAnyToolGroups.length > 1 || requiredAllToolNames.length > 0;
        const requiredAnyToolGroupNames = requiredAnyToolGroups.map((group) => {
            const formatted = formatToolNames(group, "or");
            return wrapAnyGroup ? `(${formatted})` : formatted;
        });
        return formatToolNames([
            ...requiredAnyToolGroupNames,
            ...(requiredAllToolNames.length > 0 ? [formatToolNames(requiredAllToolNames, "and")] : []),
        ], "and");
    }
    return formatToolNames(requiredAllToolNames, "and");
}
export function formatRequiredToolNamesForPrompt(constraint) {
    return formatRequiredToolNames(constraint);
}
function formatSelectableToolNames(constraint) {
    if (constraint.selectableToolNames) {
        return formatToolNames(constraint.selectableToolNames, "or");
    }
    const { requiredAllToolNames, requiredAnyToolNames } = splitRequiredToolGroups(constraint);
    return formatToolNames([...new Set([...requiredAllToolNames, ...requiredAnyToolNames])], "or");
}
function formatForbiddenToolInstruction(constraint) {
    return constraint.forbiddenToolNames.length > 0
        ? ` Do not select ${formatToolNames(constraint.forbiddenToolNames, "or")} this turn.`
        : "";
}
export function buildRequiredToolSystemPrompt(constraint) {
    return constraint.forbiddenToolNames.length > 0
        ? `Runtime tool constraint: forbidden tools this turn: ${formatToolNames(constraint.forbiddenToolNames, "or")}.`
        : "Runtime tool constraint: no tool is required by the runtime.";
}
export function stripRequiredToolSystemPrompt(systemPrompt, constraint) {
    if (!systemPrompt || !constraint) {
        return systemPrompt;
    }
    const requiredPrompt = buildRequiredToolSystemPrompt(constraint);
    const remainingParts = systemPrompt
        .split(/\n{2,}/u)
        .map((part) => part.trim())
        .filter((part) => part.length > 0 && part !== requiredPrompt && !isLegacyRequiredToolSystemPromptPart(part));
    return remainingParts.length > 0 ? remainingParts.join("\n\n") : undefined;
}
function isLegacyRequiredToolSystemPromptPart(part) {
    return (part.startsWith("The latest user message requires repository-wide file coverage.") ||
        part.startsWith("The latest user message explicitly requires delegated subagents.") ||
        part.startsWith("The latest user message explicitly restricts tool use to ") ||
        part.startsWith("The latest user message explicitly forbids tool ") ||
        part.startsWith("The latest user message explicitly requires selecting ") ||
        part.startsWith("The latest user message explicitly requires tool ") ||
        part.startsWith("The latest user message explicitly requires "));
}
export function buildRequiredToolMissingError(constraint) {
    return constraint.forbiddenToolNames.length > 0
        ? `Forbidden tool constraint remains active: ${formatToolNames(constraint.forbiddenToolNames, "or")}.`
        : "Runtime did not enforce a required tool for this turn.";
}
export function buildRequiredToolWrongSelectionError(constraint, selectedToolName) {
    return constraint.forbiddenToolNames.includes(selectedToolName)
        ? `Tool ${selectedToolName} is forbidden for this turn.`
        : `Runtime accepted tool self-selection; no required-tool substitution is enforced for ${selectedToolName}.`;
}
// ---------------------------------------------------------------------------
// Prompt deliverable repair prompts
// ---------------------------------------------------------------------------
export function buildPromptDeliverableRepairPrompt(failures) {
    return [
        "Previous response did not satisfy explicit deliverable evidence. A generic completion check based only on the latest task request found required deliverable files that are missing, blank, unchanged, or outside prompt constraints:",
        ...failures.map((failure) => `- ${describePromptDeliverableFailure(failure.reason)} ${failure.displayPath}${describePromptDeliverableFailureDetails(failure)}`),
        "",
        "Observed workspace state did not provide the required deliverable evidence.",
    ].join("\n");
}
export function describePromptDeliverableFailure(reason) {
    switch (reason) {
        case "blank":
            return "blank required file";
        case "command-failed":
            return "required command did not exit successfully";
        case "evidence-missing":
            return "missing required evidence";
        case "extra-sibling":
            return "unexpected extra file next to single-file deliverable";
        case "missing":
            return "missing required file";
        case "too-large":
            return "required file exceeds prompt size limit";
        case "unchanged":
            return "required file was not changed";
    }
}
export function describePromptDeliverableFailureDetails(failure) {
    if (failure.reason === "extra-sibling" && failure.extraPath) {
        return ` (${failure.extraPath})`;
    }
    if (failure.reason !== "too-large" || !failure.maxBytes) {
        return "";
    }
    const actual = failure.actualBytes ? `, actual ${failure.actualBytes} bytes` : "";
    const limit = failure.maxBytes;
    const limitDesc = typeof limit === "number"
        ? `must not exceed ${limit} bytes`
        : limit.inclusive
            ? `must not exceed ${limit.bytes} bytes`
            : `must be under ${limit.bytes} bytes`;
    return ` (${limitDesc}${actual})`;
}
// ---------------------------------------------------------------------------
// Provider turn budget finalization prompt
// ---------------------------------------------------------------------------
export function buildProviderTurnBudgetFinalizationPrompt(maxProviderTurns) {
    return [
        `The ordinary turn provider decision budget of ${maxProviderTurns} has been reached.`,
        "Do not call tools or request more exploration.",
        "Return the best concise final answer from the current tool results and evidence.",
        "Return only user-visible prose, not raw tool-call markup, JSON control payloads, or hidden reasoning.",
        "If the task is incomplete, say what is missing and what was already verified.",
    ].join("\n");
}
//# sourceMappingURL=runtime-prompts.js.map