/**
 * Normalization for values thrown by a final LLM adapter boundary.
 *
 * @module @deepseek-ai/dsh-llm/adapter-failure
 */
import { HarnessError } from "./error.js";
/**
 * Detach serializable provider facts from a value thrown by an adapter.
 * @param value - arbitrary value thrown during adapter dispatch or iteration.
 * @returns immutable provider-neutral facts suitable for a terminal finish chunk.
 * @internal
 */
export function normalizeLlmFailure(value) {
    const error = value instanceof Error
        ? value
        : new HarnessError(thrownMessage(value), 'UNKNOWN', { cause: value });
    // Cross-package copies preserve own data but not class identity. Trust the
    // carried facts only when both own properties agree after validation.
    const carried = ownFailureSnapshot(error);
    if (carried !== undefined && carried.code === ownErrorCode(error))
        return carried;
    return Object.freeze({
        message: errorMessage(error),
        code: harnessErrorCode(error),
    });
}
/** Render a non-Error throw without letting hostile coercion escape normalization. */
function thrownMessage(value) {
    try {
        const message = String(value);
        return message.length > 0 ? message : 'LLM adapter failed';
    }
    catch (_hostileThrownValue) {
        return 'LLM adapter failed';
    }
}
/** Read a foreign error's own data-backed `code` without invoking accessors. */
function ownErrorCode(error) {
    try {
        const descriptor = Object.getOwnPropertyDescriptor(error, 'code');
        return descriptor !== undefined && 'value' in descriptor ? descriptor.value : undefined;
    }
    catch (_sdkPropertyTrap) {
        return undefined;
    }
}
/** Snapshot an own data property without invoking an SDK-defined accessor. */
function ownFailureSnapshot(error) {
    try {
        const descriptor = Object.getOwnPropertyDescriptor(error, 'failure');
        return descriptor !== undefined && 'value' in descriptor
            ? failureSnapshot(descriptor.value)
            : undefined;
    }
    catch (_sdkPropertyTrap) {
        return undefined;
    }
}
/** Validate and detach an arbitrary serializable failure payload. */
function failureSnapshot(value) {
    if (typeof value !== 'object' || value === null)
        return undefined;
    try {
        const candidate = value;
        const message = candidate.message;
        const code = candidate.code;
        const status = candidate.status;
        const providerRetryAfterMs = candidate.providerRetryAfterMs;
        const requestId = candidate.requestId;
        if (typeof message !== 'string' || message.length === 0
            || typeof code !== 'string' || code.length === 0
            || (status !== undefined && (!Number.isInteger(status) || status < 100 || status > 599))
            || (providerRetryAfterMs !== undefined
                && (!Number.isFinite(providerRetryAfterMs) || providerRetryAfterMs <= 0))
            || (requestId !== undefined && (typeof requestId !== 'string' || requestId.length === 0)))
            return undefined;
        return Object.freeze({
            message,
            code,
            ...status === undefined ? {} : { status },
            ...providerRetryAfterMs === undefined ? {} : { providerRetryAfterMs },
            ...requestId === undefined ? {} : { requestId },
        });
    }
    catch (_sdkFailureGetter) {
        return undefined;
    }
}
/** Read an SDK error message without letting an accessor replace the primary failure. */
function errorMessage(error) {
    try {
        const message = error.message;
        if (typeof message === 'string' && message.length > 0)
            return message;
    }
    catch (_sdkMessageGetter) {
        // The fallback below preserves a serializable failure beside the original Error.
    }
    return 'LLM adapter failed';
}
/** Trust only Harness-owned codes; third-party SDK codes are not our taxonomy. */
function harnessErrorCode(error) {
    return error instanceof HarnessError ? error.code : 'UNKNOWN';
}
//# sourceMappingURL=adapter-failure.js.map