/*
 * 文件定位：Agent 模型适配层 / agentCore 内部桥接层。
 * 核心目的：把模型适配层最终产物转成 agentCore 内部实际可用的调用形态。
 * 能力要求1：actualInvocationLayer 负责拿到上游 provider/API endpoint 的真实可用调用面。
 * 能力要求2：abstractionLayer 负责根据 DSL 和格式映射完成跨厂商抽象与转换。
 * 能力要求3：本文件处在最后一步：把抽象层整理好的能力暴露成 agentCore 一看就能接入的形态。
 * 边界：负责进入 agentCore 前的最后适配，不重新处理上游 endpoint 细节。
 * 对接：需要被 runtime.modelAdapter 拉起，并和 provider/carrier、PromptPack lowering、能力抽象链路接通。
 * 实现提示：先补稳定类型契约、最小可测行为和清晰错误边界，再接入真实执行逻辑。
 */
import { checkApplicationModelCompatibility, } from "./applicationCompatibilityCheck.js";
export const applicationAdapterDescriptor = {
    capability: "application-adapter",
    route: "agent_modelAdapter.bridgingLayer",
    purpose: "wrap a compatible abstraction-layer model candidate as agentCore's direct internal model capability",
    providerPayloadCreated: false,
    unsafeSideEffects: false,
};
function isBlank(value) {
    return typeof value !== "string" || value.trim().length === 0;
}
function failure(code, message, boundary) {
    return {
        ok: false,
        error: { code, message, boundary, safeForRuntimeInspection: true },
        events: ["modelAdapter.applicationAdapter.rejected"],
    };
}
function invocationFailure(code, message, boundary) {
    return {
        ok: false,
        error: { code, message, boundary, safeForRuntimeInspection: true },
        events: ["modelAdapter.applicationAdapter.invocationRejected"],
    };
}
function hasModelInput(input) {
    return Boolean(input.prompt?.trim()) || (input.messages ?? []).some((message) => message.content.trim().length > 0);
}
function candidateId(candidate) {
    return candidate.bridgeId?.trim() || candidate.transformationId?.trim() || candidate.sourceInterfaceId?.trim() || "anonymous";
}
function normalizeCompatibility(request, runtimeId) {
    const currentCompatibility = checkApplicationModelCompatibility({
        runtimeId,
        checkId: `${request.adapterId?.trim() ?? "application-adapter"}:compatibility`,
        candidate: request.candidate,
        requiredCapabilityIds: request.requiredCapabilityIds,
        requiredFormatIds: request.requiredFormatIds,
        requestedScopes: request.requestedScopes,
        allowedScopes: request.allowedScopes,
        requireReadyBridge: true,
        contract: request.contract,
        governance: request.governance,
    });
    if (!currentCompatibility.ok) {
        return failure("COMPATIBILITY_REJECTED", currentCompatibility.error.message, currentCompatibility.error.boundary);
    }
    if (request.compatibility !== undefined) {
        if (request.compatibility.runtimeId !== runtimeId) {
            return failure("RUNTIME_MISMATCH", "application adapter compatibility belongs to a different runtime", "contract");
        }
        if (request.compatibility.candidateId !== currentCompatibility.report.candidateId) {
            return failure("COMPATIBILITY_REJECTED", "application adapter compatibility does not belong to the bridge candidate", "contract");
        }
        if (request.compatibility.compatible && !currentCompatibility.report.compatible) {
            return failure("COMPATIBILITY_REJECTED", "application adapter compatibility is stale for the current bridge candidate", "compatibility");
        }
        return request.compatibility;
    }
    return currentCompatibility.report;
}
function createInvoke(adapterId, candidate, invoker) {
    return async (input) => {
        if (input === undefined) {
            return invocationFailure("MISSING_INVOCATION_INPUT", "application adapter invocation requires an input envelope", "input");
        }
        if (!hasModelInput(input)) {
            return invocationFailure("MISSING_MODEL_INPUT", "application adapter invocation requires prompt or messages", "input");
        }
        const invocationId = input.invocationId?.trim() || `${adapterId}:dry-run`;
        if (invoker === undefined) {
            return {
                ok: true,
                invocationId,
                output: {
                    kind: "agentCore.modelAdapter.applicationInvocationOutput",
                    content: {
                        candidateId: candidateId(candidate),
                        status: "dry-run",
                    },
                    dryRun: true,
                    providerPayloadCreated: false,
                    unsafeSideEffects: false,
                },
                events: ["modelAdapter.applicationAdapter.dryRunInvoked"],
            };
        }
        try {
            return await invoker({ ...input, invocationId });
        }
        catch (error) {
            return invocationFailure("INVOKER_REJECTED", error instanceof Error ? error.message : "application adapter invoker rejected the invocation", "invocation");
        }
    };
}
export function createApplicationModelAdapter(request) {
    if (request === undefined || isBlank(request.runtimeId)) {
        return failure("MISSING_RUNTIME_ID", "application adapter requires runtimeId", "input");
    }
    const runtimeId = (request.runtimeId ?? "").trim();
    const adapterId = request.adapterId?.trim();
    if (!adapterId) {
        return failure("MISSING_ADAPTER_ID", "application adapter requires adapterId", "input");
    }
    if (request.candidate === undefined) {
        return failure("MISSING_BRIDGE_CANDIDATE", "application adapter requires an abstraction-layer bridge candidate", "input");
    }
    if (request.candidate.runtimeId !== runtimeId) {
        return failure("RUNTIME_MISMATCH", "application adapter candidate belongs to a different runtime", "contract");
    }
    const compatibility = normalizeCompatibility(request, runtimeId);
    if ("ok" in compatibility) {
        return compatibility;
    }
    if (!compatibility.compatible) {
        return failure("INCOMPATIBLE_BRIDGE_CANDIDATE", "application adapter only exposes bridge candidates that are usable by agentCore", "compatibility");
    }
    return {
        ok: true,
        adapter: {
            kind: "agentCore.modelAdapter.applicationAdapter",
            runtimeId,
            adapterId,
            candidateId: compatibility.candidateId,
            readiness: "ready",
            capabilities: request.candidate.capabilities,
            formats: request.candidate.formats,
            acceptedScopes: compatibility.acceptedScopes,
            providerPayloadCreated: false,
            unsafeSideEffects: false,
            invoke: createInvoke(adapterId, request.candidate, request.invoker),
        },
        compatibility,
        events: ["modelAdapter.applicationAdapter.created"],
    };
}
