const MAX_CAPABILITY_NAME_LENGTH = 120;
export function normalizeCapabilityNames(values) {
    const seen = new Set();
    const normalized = [];
    for (const value of values ?? []) {
        const name = value.trim().slice(0, MAX_CAPABILITY_NAME_LENGTH);
        if (!name || seen.has(name))
            continue;
        seen.add(name);
        normalized.push(name);
    }
    return normalized;
}
export function buildCapabilityInjection(input = {}) {
    const mcpServers = normalizeCapabilityNames([...(input.mcpAllowlist ?? []), ...(input.mcpServers ?? [])]);
    const skills = normalizeCapabilityNames([...(input.skillNames ?? []), ...(input.skills ?? [])]);
    const hooks = normalizeCapabilityNames([...(input.hookNames ?? []), ...(input.hooks ?? [])]);
    const tools = normalizeCapabilityNames(input.tools);
    const requiresMcp = input.requireMcp ?? false;
    const requiresToolCalling = input.requiresToolCalling ?? tools.length > 0;
    const summary = {
        mcp: summarizeCapabilityKind(mcpServers),
        skills: summarizeCapabilityKind(skills),
        hooks: summarizeCapabilityKind(hooks),
        tools: summarizeCapabilityKind(tools),
        requiresMcp,
        requiresToolCalling,
        rationale: [
            `mcp=${mcpServers.length}`,
            `skills=${skills.length}`,
            `hooks=${hooks.length}`,
            `tools=${tools.length}`,
            `requiresMcp=${requiresMcp ? "true" : "false"}`,
            `requiresToolCalling=${requiresToolCalling ? "true" : "false"}`,
        ].join("; "),
    };
    return {
        mcpServers,
        skills,
        hooks,
        tools,
        requiresMcp,
        requiresToolCalling,
        summary,
    };
}
export function applyCapabilityInjectionToRouting(routing, injection) {
    return {
        ...routing,
        mcpServers: [...injection.mcpServers],
        skills: [...injection.skills],
        tools: [...injection.tools],
        hooks: [...injection.hooks],
        assignedCapabilities: {
            ...(routing.assignedCapabilities ?? {}),
            mcpServers: [...injection.mcpServers],
            skills: [...injection.skills],
            tools: [...injection.tools],
            hooks: [...injection.hooks],
        },
        requiresMcp: injection.requiresMcp,
        requiresToolCalling: routing.requiresToolCalling ?? injection.requiresToolCalling,
        rationale: appendRationale(routing.rationale, `capability envelope: ${injection.summary.rationale}`),
    };
}
export function renderCapabilityInjectionSummary(injection) {
    return [
        `MCP selected: ${formatCapabilityKind(injection.summary.mcp)}; required=${injection.requiresMcp ? "true" : "false"}; failure-policy=${injection.requiresMcp ? "strict" : "required-only"}`,
        `Skills selected: ${formatCapabilityKind(injection.summary.skills)}`,
        `Hooks active: ${formatCapabilityKind(injection.summary.hooks)}`,
        `Tools available: ${formatCapabilityKind(injection.summary.tools)}; tool-calling-required=${injection.requiresToolCalling ? "true" : "false"}`,
        "Do not activate every available MCP server or skill; use only capabilities needed for this request.",
        "Optional MCP failures are warnings unless MCP is explicitly required for this node.",
    ].join("\n");
}
function summarizeCapabilityKind(names) {
    return {
        enabled: names.length > 0,
        count: names.length,
        names: [...names],
    };
}
function formatCapabilityKind(summary) {
    if (!summary.enabled)
        return "disabled";
    const preview = summary.names.slice(0, 8).join(", ");
    const more = summary.count > 8 ? `, +${summary.count - 8} more` : "";
    return `enabled (${summary.count}) [${preview}${more}]`;
}
function appendRationale(existing, addition) {
    const trimmed = existing?.trim();
    return trimmed ? `${trimmed}; ${addition}` : addition;
}
