"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderWorkflowStateContext = renderWorkflowStateContext;
exports.renderWorkflowStateSummary = renderWorkflowStateSummary;
const plan_progress_1 = require("../workflows/plan-progress");
const template_bindings_1 = require("../workflows/template-bindings");
const prompt_text_1 = require("./prompt-text");
const types_1 = require("./types");
const EXECUTE_DEPENDENCY_EVIDENCE_RECENT_COUNT = 3;
const CLOSING_REPRESENTATIVE_EVIDENCE_COUNT = 5;
const STEP_EVIDENCE_ITEM_COUNT = 2;
const STEP_EVIDENCE_ITEM_CHARACTERS = 120;
const PLAN_DIRECT_STEP_SUMMARY_COUNT = 20;
const PLAN_GROUP_ACTIVE_STEP_SUMMARY_COUNT = 3;
const PLAN_GROUP_COMPLETED_STEP_SUMMARY_COUNT = 1;
function renderWorkflowStateContext(workflow) {
    switch (workflow.mode) {
        case types_1.WORKER_RUN_MODES.workflowPlan:
            return renderWorkflowPlanStateContext(workflow.state);
        case types_1.WORKER_RUN_MODES.workflowSelect:
            return renderWorkflowSelectStateContext(workflow.state);
        case types_1.WORKER_RUN_MODES.workflowExecute:
            return renderWorkflowExecuteStateContext(workflow.state, workflow.currentStepId);
        case types_1.WORKER_RUN_MODES.workflowReconcileStepBatch:
            return renderWorkflowStepBatchReconciliationContext(workflow);
        case types_1.WORKER_RUN_MODES.workflowClosing:
            return renderWorkflowClosingStateContext(workflow.state);
    }
    return assertNeverWorkflowMode(workflow.mode);
}
function renderWorkflowStateSummary(state) {
    if (state === null) {
        return prompt_text_1.PROMPT_TEXT.none;
    }
    return JSON.stringify(buildWorkflowStateSummary(state));
}
function renderWorkflowPlanStateContext(state) {
    if (state === null) {
        return [prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary, `  ${prompt_text_1.PROMPT_TEXT.none}`];
    }
    return [
        prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary,
        ...renderTopLevelCompactLines(buildWorkflowPlanningStateSummary(state), 2),
    ];
}
function renderWorkflowSelectStateContext(state) {
    if (state === null) {
        return [prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary, `  ${prompt_text_1.PROMPT_TEXT.none}`];
    }
    return [
        prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary,
        ...renderTopLevelCompactLines(buildWorkflowSelectionStateSummary(state), 2),
    ];
}
function renderWorkflowExecuteStateContext(state, currentStepId) {
    if (state === null) {
        return [
            prompt_text_1.PROMPT_TEXT.fieldExecutionGuidance,
            `  ${prompt_text_1.PROMPT_TEXT.none}`,
            prompt_text_1.PROMPT_TEXT.fieldCurrentExecutableStep,
            `  ${prompt_text_1.PROMPT_TEXT.none}`,
            prompt_text_1.PROMPT_TEXT.fieldCompletedStepEvidence,
            `  ${prompt_text_1.PROMPT_TEXT.none}`,
            prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary,
            `  ${prompt_text_1.PROMPT_TEXT.none}`,
        ];
    }
    const currentStep = state.plan === null
        ? null
        : currentStepId
            ? (0, plan_progress_1.findWorkflowStepById)(state.plan, currentStepId)
            : null;
    const completedEvidence = buildWorkflowExecuteCompletedEvidenceContext(state.plan, currentStep);
    return [
        prompt_text_1.PROMPT_TEXT.fieldExecutionGuidance,
        ...renderScalarListLines(state.executionGuidance ?? [], 2),
        prompt_text_1.PROMPT_TEXT.fieldCurrentExecutableStep,
        ...renderTopLevelCompactLines(currentStep === null
            ? null
            : buildWorkflowCurrentStepContext(currentStep), 2),
        prompt_text_1.PROMPT_TEXT.fieldCompletedStepEvidence,
        ...renderTopLevelCompactLines(completedEvidence, 2),
        prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary,
        ...renderTopLevelCompactLines(buildWorkflowStateSummary(state), 2),
    ];
}
function renderWorkflowStepBatchReconciliationContext(workflow) {
    return [
        prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary,
        ...renderTopLevelCompactLines(workflow.state === null
            ? null
            : buildWorkflowStateSummary(workflow.state), 2),
        "Step batch reconciliation input:",
        ...renderTopLevelCompactLines(workflow.stepBatchReconciliation ?? null, 2),
    ];
}
function renderWorkflowClosingStateContext(state) {
    if (state === null) {
        return [
            prompt_text_1.PROMPT_TEXT.fieldExecutionGuidance,
            `  ${prompt_text_1.PROMPT_TEXT.none}`,
            prompt_text_1.PROMPT_TEXT.fieldCompletedStepEvidence,
            `  ${prompt_text_1.PROMPT_TEXT.none}`,
            prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary,
            `  ${prompt_text_1.PROMPT_TEXT.none}`,
        ];
    }
    const completedEvidence = buildWorkflowClosingCompletedEvidenceContext(state.plan);
    return [
        prompt_text_1.PROMPT_TEXT.fieldExecutionGuidance,
        ...renderScalarListLines(state.executionGuidance ?? [], 2),
        prompt_text_1.PROMPT_TEXT.fieldCompletedStepEvidence,
        ...renderTopLevelCompactLines(completedEvidence, 2),
        prompt_text_1.PROMPT_TEXT.fieldWorkflowStateSummary,
        ...renderTopLevelCompactLines(buildWorkflowStateSummary(state), 2),
    ];
}
function buildWorkflowCurrentStepContext(step) {
    return compactDefinedProperties({
        id: step.id,
        kind: step.kind,
        title: step.title,
        objective: step.objective,
        instructions: step.instructions,
        doneWhen: step.doneWhen,
        humanHandoffWhen: step.humanHandoffWhen,
        dependencies: step.dependsOnStepIds,
        targetTemplateName: step.targetTemplateName,
        callSiteId: step.callSiteId,
        sourceTemplateName: step.sourceTemplateName,
        sourceTemplateDigest: step.sourceTemplateDigest,
        expansionGroupId: step.expansionGroupId,
    });
}
function buildWorkflowExecuteCompletedEvidenceContext(plan, currentStep) {
    if (plan === null) {
        return null;
    }
    const completedSteps = plan.steps.filter(plan_progress_1.isWorkflowStepDone);
    const dependencyStepIds = new Set(currentStep?.dependsOnStepIds ?? []);
    const dependencyStepEvidence = completedSteps
        .filter((step) => dependencyStepIds.has(step.id))
        .map(buildWorkflowStepEvidence);
    const selectedStepIds = new Set(dependencyStepEvidence.map((step) => step.id));
    const recentStepEvidence = completedSteps
        .filter((step) => !selectedStepIds.has(step.id))
        .slice(-EXECUTE_DEPENDENCY_EVIDENCE_RECENT_COUNT)
        .map(buildWorkflowStepEvidence);
    for (const step of recentStepEvidence) {
        selectedStepIds.add(step.id);
    }
    return compactDefinedProperties({
        summary: buildWorkflowStepOutcomeSummary(plan.steps),
        dependencyStepEvidence: dependencyStepEvidence.length > 0 ? dependencyStepEvidence : undefined,
        recentStepEvidence: recentStepEvidence.length > 0 ? recentStepEvidence : undefined,
        omittedCompletedStepEvidenceCount: Math.max(0, completedSteps.length - selectedStepIds.size),
    });
}
function buildWorkflowClosingCompletedEvidenceContext(plan) {
    if (plan === null) {
        return null;
    }
    const completedSteps = plan.steps.filter(plan_progress_1.isWorkflowStepDone);
    return compactDefinedProperties({
        summary: buildWorkflowStepOutcomeSummary(plan.steps),
        representativeStepEvidence: completedSteps
            .slice(-CLOSING_REPRESENTATIVE_EVIDENCE_COUNT)
            .map(buildWorkflowStepEvidence),
        omittedCompletedStepEvidenceCount: Math.max(0, completedSteps.length - CLOSING_REPRESENTATIVE_EVIDENCE_COUNT),
    });
}
function buildWorkflowStepEvidence(step) {
    const result = step.result;
    return compactDefinedProperties({
        id: step.id,
        kind: step.kind,
        title: step.title,
        outcome: result?.outcome,
        resultSummary: result?.resultSummary,
        evidence: result?.evidence
            ?.slice(0, STEP_EVIDENCE_ITEM_COUNT)
            .map((item) => truncateInlinePromptText(item, STEP_EVIDENCE_ITEM_CHARACTERS)),
    });
}
function buildWorkflowPlanningStateSummary(state) {
    return compactDefinedProperties({
        ...buildWorkflowStateSummary(state),
        executionGuidance: state.executionGuidance,
        dependencySyncState: buildWorkflowDependencySyncStateSummary(state.dependencySyncState),
        mergeContext: state.mergeContext,
        plan: buildWorkflowPlanProgressSummary(state.plan),
        finalResult: buildWorkflowFinalResultSummary(state.finalResult),
    });
}
function buildWorkflowSelectionStateSummary(state) {
    return compactDefinedProperties({
        workflowSurface: state.workflowSurface,
        workflowTemplate: buildWorkflowTemplateBindingSummary((0, template_bindings_1.getActiveWorkflowTemplateBinding)(state)),
        sideWorkflowTemplates: buildSideWorkflowTemplateBindingsSummary(state),
        schedule: state.schedule,
        scheduledRun: state.scheduledRun,
        recurring: state.recurring,
        configOverrides: state.configOverrides,
        pendingWorkflowStartApprovalIntent: state.pendingWorkflowStartApprovalIntent,
        pendingPlanningIntent: state.pendingPlanningIntent,
        pendingPlanningReason: state.pendingPlanningReason,
        pendingPlanningSource: state.pendingPlanningSource,
    });
}
function buildWorkflowStateSummary(state) {
    return compactDefinedProperties({
        version: state.version,
        planRevision: state.planRevision,
        workflowSurface: state.workflowSurface,
        workflowTemplate: buildWorkflowTemplateBindingSummary((0, template_bindings_1.getActiveWorkflowTemplateBinding)(state)),
        parentLink: state.parentLink,
        originLink: state.originLink,
        executionContract: state.executionContract,
        priorityRank: state.priorityRank,
        schedule: state.schedule,
        scheduledRun: state.scheduledRun,
        recurring: state.recurring,
        nextRunAt: state.nextRunAt,
        lastRunAt: state.lastRunAt,
        lastOutcome: state.lastOutcome,
        predictedTouchedPaths: state.predictedTouchedPaths,
        configOverrides: state.configOverrides,
        needsHumanReason: state.needsHumanReason,
        pendingWorkflowStartApprovalIntent: state.pendingWorkflowStartApprovalIntent,
        pendingPlanningIntent: state.pendingPlanningIntent,
        pendingPlanningReason: state.pendingPlanningReason,
        pendingPlanningSource: state.pendingPlanningSource,
        autoMergeState: state.autoMergeState,
        consecutiveAiRuns: state.consecutiveAiRuns,
        totalAiRunHours: state.totalAiRunHours,
    });
}
function buildWorkflowPlanProgressSummary(plan) {
    if (plan === null) {
        return null;
    }
    const groupedSubtreeSteps = groupWorkflowRefSubtreeSteps(plan.steps);
    const groupedStepIds = new Set([...groupedSubtreeSteps.values()].flatMap((steps) => steps.map((step) => step.id)));
    const directSteps = plan.steps.filter((step) => !groupedStepIds.has(step.id));
    return {
        stepCount: plan.steps.length,
        ...buildWorkflowStepOutcomeSummary(plan.steps),
        steps: buildWorkflowPlanStepListSummary(directSteps, PLAN_DIRECT_STEP_SUMMARY_COUNT),
        expandedWorkflowRefs: groupedSubtreeSteps.size > 0
            ? [...groupedSubtreeSteps.entries()].map(([, steps]) => buildWorkflowRefSubtreeSummary(steps))
            : undefined,
    };
}
function groupWorkflowRefSubtreeSteps(steps) {
    const groups = new Map();
    for (const step of steps) {
        if (step.originSubtreeKey === undefined) {
            continue;
        }
        groups.set(step.originSubtreeKey, [
            ...(groups.get(step.originSubtreeKey) ?? []),
            step,
        ]);
    }
    return groups;
}
function buildWorkflowRefSubtreeSummary(steps) {
    const firstStep = steps[0];
    return compactDefinedProperties({
        originSubtreeKey: firstStep?.originSubtreeKey,
        targetTemplateName: firstStep?.originWorkflowRef?.targetTemplateName ??
            firstStep?.targetTemplateName,
        sourceTemplateName: firstStep?.originWorkflowRef?.sourceTemplateName ??
            firstStep?.sourceTemplateName,
        callSiteId: firstStep?.originWorkflowRef?.callSiteId ?? firstStep?.callSiteId,
        stepCount: steps.length,
        ...buildWorkflowStepOutcomeSummary(steps),
        steps: buildWorkflowPlanStepListSummary(steps, resolveWorkflowRefGroupStepSummaryCount(steps)),
    });
}
function resolveWorkflowRefGroupStepSummaryCount(steps) {
    return steps.some((step) => step.result === null)
        ? PLAN_GROUP_ACTIVE_STEP_SUMMARY_COUNT
        : PLAN_GROUP_COMPLETED_STEP_SUMMARY_COUNT;
}
function buildWorkflowPlanStepListSummary(steps, maxSteps) {
    if (steps.length === 0) {
        return undefined;
    }
    const selectedSteps = selectWorkflowPlanSummarySteps(steps, maxSteps);
    return compactDefinedProperties({
        items: selectedSteps.map(buildWorkflowPlanStepSummary),
        omittedStepCount: Math.max(0, steps.length - selectedSteps.length),
    });
}
function selectWorkflowPlanSummarySteps(steps, maxSteps) {
    const selectedSteps = [];
    const selectedStepIds = new Set();
    for (const step of steps.filter((entry) => entry.result === null)) {
        appendSelectedWorkflowPlanStep(step, selectedSteps, selectedStepIds, maxSteps);
    }
    for (const step of steps.filter(plan_progress_1.isWorkflowStepDone).slice(-3)) {
        appendSelectedWorkflowPlanStep(step, selectedSteps, selectedStepIds, maxSteps);
    }
    for (const step of steps) {
        appendSelectedWorkflowPlanStep(step, selectedSteps, selectedStepIds, maxSteps);
    }
    return selectedSteps;
}
function appendSelectedWorkflowPlanStep(step, selectedSteps, selectedStepIds, maxSteps) {
    if (selectedSteps.length >= maxSteps || selectedStepIds.has(step.id)) {
        return;
    }
    selectedSteps.push(step);
    selectedStepIds.add(step.id);
}
function buildWorkflowPlanStepSummary(step) {
    return compactDefinedProperties({
        id: step.id,
        kind: step.kind,
        title: step.title,
        objective: step.objective,
        doneWhen: step.doneWhen,
        dependsOnStepIds: step.dependsOnStepIds,
        targetTemplateName: step.targetTemplateName,
        callSiteId: step.callSiteId,
        childKey: step.childKey,
        childIssueRef: step.childIssueRef,
        suggestedTemplate: step.suggestedTemplate,
        bindingHints: step.bindingHints,
        inputs: step.inputs,
        outputs: step.outputs,
        done: (0, plan_progress_1.isWorkflowStepDone)(step),
        result: buildWorkflowStepResultSummary(step),
    });
}
function buildWorkflowTemplateBindingSummary(binding) {
    if (binding === null || binding === undefined) {
        return undefined;
    }
    return compactDefinedProperties({
        selector: binding.selector,
        resolution: binding.resolution,
    });
}
function buildSideWorkflowTemplateBindingsSummary(state) {
    const sideBindings = Object.entries(state.workflowTemplates)
        .filter(([surface]) => surface !== state.workflowSurface)
        .map(([surface, binding]) => compactDefinedProperties({
        surface: surface,
        ...buildWorkflowTemplateBindingSummary(binding),
    }));
    return sideBindings.length > 0 ? sideBindings : undefined;
}
function buildWorkflowStepResultSummary(step) {
    if (step.result === null) {
        return undefined;
    }
    return compactDefinedProperties({
        outcome: step.result.outcome,
        resultSummary: step.result.resultSummary,
        evidence: step.result.evidence,
    });
}
function buildWorkflowDependencySyncStateSummary(dependencySyncState) {
    if (dependencySyncState === undefined) {
        return undefined;
    }
    return {
        managedDependencies: dependencySyncState.managedDependencies.map((dependency) => ({
            issueId: dependency.issueId,
            overlappingPaths: dependency.overlappingPaths,
            completionRequeuedAt: dependency.completionRequeuedAt,
        })),
        appliedAutoBlockers: dependencySyncState.appliedAutoBlockers.map((blocker) => ({
            issueId: blocker.issueId,
            overlappingPaths: blocker.overlappingPaths,
        })),
    };
}
function buildWorkflowFinalResultSummary(finalResult) {
    if (finalResult === null) {
        return null;
    }
    return compactDefinedProperties({
        outcome: finalResult.outcome,
        resultSummary: finalResult.resultSummary,
        evidence: finalResult.evidence,
    });
}
function buildWorkflowStepOutcomeSummary(steps) {
    const completedStepCount = steps.filter(plan_progress_1.isWorkflowStepDone).length;
    const failedStepCount = steps.filter((step) => step.result?.outcome === "fail").length;
    const waitingStepCount = steps.filter((step) => step.result?.outcome === "wait_human").length;
    return {
        completedStepCount,
        failedStepCount,
        waitingStepCount,
        incompleteStepCount: steps.length - completedStepCount - failedStepCount - waitingStepCount,
    };
}
function truncateInlinePromptText(value, maxCharacters) {
    const singleLineValue = value.replaceAll("\n", "\\n");
    if (singleLineValue.length <= maxCharacters) {
        return singleLineValue;
    }
    const marker = "...[truncated]";
    return `${singleLineValue.slice(0, Math.max(0, maxCharacters - marker.length))}${marker}`;
}
function compactDefinedProperties(value) {
    return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
}
function renderScalarListLines(value, indent = 0) {
    const prefix = " ".repeat(indent);
    if (value.length === 0) {
        return [`${prefix}${prompt_text_1.PROMPT_TEXT.none}`];
    }
    return value.map((entry) => `${prefix}- ${formatPromptScalar(entry)}`);
}
function renderTopLevelCompactLines(value, indent = 0) {
    const prefix = " ".repeat(indent);
    if (value === null || value === undefined) {
        return [`${prefix}${prompt_text_1.PROMPT_TEXT.none}`];
    }
    if (Array.isArray(value)) {
        return renderCompactListLines(value, indent);
    }
    if (typeof value === "object") {
        const entries = Object.entries(value).filter(([, entry]) => entry !== undefined);
        if (entries.length === 0) {
            return [`${prefix}${prompt_text_1.PROMPT_TEXT.none}`];
        }
        return entries.map(([key, entry]) => `${prefix}- ${key}: ${formatCompactPromptValue(entry)}`);
    }
    return [`${prefix}${formatPromptScalar(value)}`];
}
function renderCompactListLines(value, indent = 0) {
    const prefix = " ".repeat(indent);
    if (value.length === 0) {
        return [`${prefix}${prompt_text_1.PROMPT_TEXT.none}`];
    }
    return value.map((entry) => `${prefix}- ${formatCompactPromptValue(entry)}`);
}
function formatCompactPromptValue(value) {
    if (value === null || value === undefined) {
        return prompt_text_1.PROMPT_TEXT.none;
    }
    if (Array.isArray(value) || typeof value === "object") {
        return JSON.stringify(value);
    }
    return formatPromptScalar(value);
}
function formatPromptScalar(value) {
    return String(value).replaceAll("\n", "\\n");
}
function assertNeverWorkflowMode(mode) {
    throw new Error(`Unsupported workflow mode: ${String(mode)}`);
}
