/*
 * 文件定位：Agent 模型适配层 / 真实上游调用层 / 非官方/自定义上游格式。
 * 核心目的：接收自定义上游格式传入或配置出的能力说明。
 * 能力要求1：需要把外部不规范能力描述先收拢成可检查对象。
 * 能力要求2：后续再交给能力映射和兼容核心判断是否能进入 agentCore。
 * 边界：只处理上游实际调用面，不在这里定义 agentCore 使用 AI 的统一方式。
 * 对接：需要被 runtime.modelAdapter 拉起，并和 provider/carrier、PromptPack lowering、能力抽象链路接通。
 * 实现提示：先补稳定类型契约、最小可测行为和清晰错误边界，再接入真实执行逻辑。
 */
export const customFormatCapabilityReceiverDescriptor = {
    layer: "agent_modelAdapter.actualInvocationLayer.customFormat",
    capability: "customFormat.capabilityReceiver",
    purpose: "receive an external custom provider capability description into an inspection-safe envelope",
    dryRun: true,
    unsafeSideEffects: false,
    rawProviderFieldsExposed: false,
};
function cleanText(value) {
    const cleaned = value?.trim();
    return cleaned === undefined || cleaned.length === 0 ? undefined : cleaned;
}
function cleanList(values) {
    return [...new Set((values ?? []).map((value) => value.trim()).filter(Boolean))].sort();
}
function isRecord(value) {
    return typeof value === "object" && value !== null && !Array.isArray(value);
}
function failure(code, message, boundary) {
    return {
        ok: false,
        error: { code, message, boundary, safeForRuntimeInspection: true, rawProviderFieldsExposed: false },
        events: ["customFormat.capability.receive.rejected"],
    };
}
function hasCapabilitySignal(request) {
    return (cleanList(request.inputChannels).length > 0 ||
        cleanList(request.outputChannels).length > 0 ||
        request.toolUse === true ||
        request.streaming === true ||
        request.fileExchange === true ||
        request.contextWindowTokens !== undefined);
}
export function receiveCustomFormatCapability(request) {
    const providerId = request?.providerId?.trim();
    const endpointId = request?.endpointId?.trim();
    const capabilityId = request?.capabilityId?.trim();
    if (request === undefined || providerId === undefined || providerId.length === 0) {
        return failure("MISSING_PROVIDER_ID", "customFormat capability receiver requires providerId", "input");
    }
    if (endpointId === undefined || endpointId.length === 0) {
        return failure("MISSING_ENDPOINT_ID", "customFormat capability receiver requires endpointId", "input");
    }
    if (capabilityId === undefined || capabilityId.length === 0) {
        return failure("MISSING_CAPABILITY_ID", "customFormat capability receiver requires capabilityId", "input");
    }
    if (!hasCapabilitySignal(request)) {
        return failure("MISSING_CAPABILITY_SIGNAL", "customFormat capability receiver requires at least one input, output, tool, stream, file, or context signal", "input");
    }
    if (request.contextWindowTokens !== undefined &&
        (!Number.isSafeInteger(request.contextWindowTokens) || request.contextWindowTokens <= 0)) {
        return failure("INVALID_CONTEXT_WINDOW", "customFormat contextWindowTokens must be a positive safe integer when provided", "provider-config");
    }
    if (request.raw !== undefined && !isRecord(request.raw)) {
        return failure("INVALID_RAW_ENVELOPE", "customFormat raw capability material must be a plain record", "input");
    }
    if (request.contract?.accepted === false) {
        return failure("CONTRACT_REJECTED", request.contract.reason ?? "runtime contract surface rejected the customFormat capability", "contract");
    }
    if (request.governance?.accepted === false) {
        return failure("GOVERNANCE_REJECTED", request.governance.reason ?? "runtime governance rejected the customFormat capability", "governance");
    }
    const inputChannels = cleanList(request.inputChannels);
    const outputChannels = cleanList(request.outputChannels);
    return {
        ok: true,
        capability: {
            providerId,
            endpointId,
            capabilityId,
            label: cleanText(request.label) ?? capabilityId,
            description: cleanText(request.description),
            inputChannels,
            outputChannels,
            featureFlags: {
                toolUse: request.toolUse === true,
                streaming: request.streaming === true,
                fileExchange: request.fileExchange === true,
                contextWindowTokens: request.contextWindowTokens,
            },
            rawEnvelope: {
                retained: false,
                keyHints: Object.keys(request.raw ?? {}).sort(),
            },
            metadata: request.metadata ?? {},
            trace: {
                correlationId: cleanText(request.trace?.correlationId),
                callerId: cleanText(request.trace?.callerId),
                source: cleanText(request.trace?.source),
            },
            audit: {
                receivedBy: "customFormat.capabilityReceiver",
                dryRun: true,
                unsafeSideEffects: false,
                rawProviderFieldsExposed: false,
                next: "capabilityDefiner",
            },
        },
        events: ["customFormat.capability.received"],
    };
}
