import { InvalidToolInputError } from "ai";
import { hasRetryableProperty, isNoOutputError, LLMProviderError, } from "../error.js";
export { hasRetryableProperty };
export class RetriesExhaustedError extends Error {
    name = "RetriesExhaustedError";
    attempts;
    totalTimeMs;
    constructor(attempts, totalTimeMs, cause) {
        super(`All ${attempts} retry attempts exhausted after ${totalTimeMs}ms`);
        this.attempts = attempts;
        this.totalTimeMs = totalTimeMs;
        this.cause = cause;
    }
}
export class AbortedError extends Error {
    name = "AbortedError";
    constructor(message = "Request aborted") {
        super(message);
    }
}
/**
 * Error thrown when a stream has been idle for too long.
 * This is a retryable error that triggers the retry logic.
 */
export class StallTimeoutError extends Error {
    name = "StallTimeoutError";
    isRetryable = true;
    idleTimeMs;
    maxIdleTimeMs;
    constructor(idleTimeMs, maxIdleTimeMs) {
        super(`Stream stalled: no activity for ${idleTimeMs}ms (max: ${maxIdleTimeMs}ms)`);
        this.idleTimeMs = idleTimeMs;
        this.maxIdleTimeMs = maxIdleTimeMs;
    }
}
/**
 * Wraps an error for consistent error handling.
 */
export function wrapError(err, provider) {
    if (err instanceof LLMProviderError) {
        return err;
    }
    if (isNoOutputError(err)) {
        return new LLMProviderError({
            provider: provider,
            message: err instanceof Error ? err.message : "No output generated by model",
            type: "no_output",
            isRetryable: true,
            cause: err,
        });
    }
    if (err instanceof AbortedError) {
        return new LLMProviderError({
            provider: provider,
            message: err.message,
            type: "aborted",
            isRetryable: false,
            cause: err,
        });
    }
    if (err instanceof RetriesExhaustedError) {
        // Create LLMProviderError from the underlying cause to preserve type, statusCode, data, etc.
        // So we can preserve the type of the underlying error, which helps us report the correct error to the user (and observability)
        const underlyingError = new LLMProviderError({
            provider: provider,
            message: err.message,
            cause: err.cause,
        });
        // And we set it here because we do not want the internal cause to be the one that determins the retry
        underlyingError.isRetryable = false;
        return underlyingError;
    }
    if (InvalidToolInputError.isInstance(err)) {
        return new LLMProviderError({
            provider: provider,
            message: err.message,
            type: "validation_error",
            isRetryable: true,
            cause: err,
        });
    }
    return new LLMProviderError({
        provider: provider,
        cause: err,
    });
}
//# sourceMappingURL=errors.js.map