// Force strict mode and setup for ESM
"use strict";
import {
  createDebugLogger
} from "./chunk-XP27SJMH.js";
import {
  require_undici
} from "./chunk-E7E2MFYM.js";
import {
  init_esbuild_shims
} from "./chunk-A4BMJM77.js";
import {
  __name,
  __toESM
} from "./chunk-J2S4EL5Y.js";

// packages/core/src/utils/runtimeFetchOptions.ts
init_esbuild_shims();
var import_undici = __toESM(require_undici(), 1);
var debugLogger = createDebugLogger("RUNTIME_FETCH");
function detectRuntime() {
  if (typeof process !== "undefined" && process.versions?.["bun"]) {
    return "bun";
  }
  if (typeof process !== "undefined" && process.versions?.node) {
    return "node";
  }
  return "unknown";
}
__name(detectRuntime, "detectRuntime");
function buildRuntimeFetchOptions(sdkType, proxyUrl) {
  const runtime = detectRuntime();
  switch (runtime) {
    case "bun": {
      if (sdkType === "openai") {
        return {
          fetchOptions: {
            timeout: false
          }
        };
      } else {
        const bunFetch = /* @__PURE__ */ __name(async (input, init) => {
          const bunFetchOptions = {
            ...init,
            // @ts-expect-error - Bun-specific timeout option
            timeout: false
          };
          return fetch(input, bunFetchOptions);
        }, "bunFetch");
        return {
          fetch: bunFetch
        };
      }
    }
    case "node": {
      return buildFetchOptionsWithDispatcher(sdkType, proxyUrl);
    }
    default: {
      return buildFetchOptionsWithDispatcher(sdkType, proxyUrl);
    }
  }
}
__name(buildRuntimeFetchOptions, "buildRuntimeFetchOptions");
var dispatcherCache = /* @__PURE__ */ new Map();
var proxyFailureCounts = /* @__PURE__ */ new Map();
var NO_DISPATCHER_FALLBACK = {
  openai: void 0,
  anthropic: {}
};
function getOrCreateSharedDispatcher(proxyUrl) {
  const cached = dispatcherCache.get(proxyUrl);
  if (cached) {
    return cached;
  }
  const dispatcher = new import_undici.ProxyAgent({
    uri: proxyUrl,
    headersTimeout: 0,
    bodyTimeout: 0,
    keepAliveTimeout: 6e4
  });
  dispatcherCache.set(proxyUrl, dispatcher);
  return dispatcher;
}
__name(getOrCreateSharedDispatcher, "getOrCreateSharedDispatcher");
function extractHostnameFromProxyUrl(proxyUrl) {
  try {
    const url = new URL(proxyUrl);
    if (url.hostname) {
      return url.port ? `${url.hostname}:${url.port}` : url.hostname;
    }
  } catch {
  }
  const match = proxyUrl.match(/@([^:/\s]+)(:\d+)?/);
  return match ? match[1] + (match[2] ?? "") : redactProxyCredentials(proxyUrl);
}
__name(extractHostnameFromProxyUrl, "extractHostnameFromProxyUrl");
function hasPlausibleProxyPort(host) {
  const portMatch = host.match(/:(\d{1,5})$/);
  if (!portMatch) {
    return false;
  }
  const port = Number(portMatch[1]);
  return port >= 80 && port <= 65535;
}
__name(hasPlausibleProxyPort, "hasPlausibleProxyPort");
function hasLocalOrProxyLikeHost(host) {
  const hostWithoutPort = host.replace(/:\d{1,5}$/, "").toLowerCase();
  if (hostWithoutPort === "localhost") {
    return true;
  }
  if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostWithoutPort)) {
    return true;
  }
  return hostWithoutPort.split(/[.-]/).some((label) => /^(proxy|gateway|gw|squid)\d*$/.test(label));
}
__name(hasLocalOrProxyLikeHost, "hasLocalOrProxyLikeHost");
function hasNetworkErrorContext(message, offset) {
  const context = message.slice(Math.max(0, offset - 80), offset).toLowerCase();
  return /\b(connect|dispatcher|econnrefused|econnreset|enotfound|etimedout|proxy|tunnel)\b/.test(
    context
  );
}
__name(hasNetworkErrorContext, "hasNetworkErrorContext");
function shouldRedactTokenOnlyCredential(host, message, offset) {
  return hasPlausibleProxyPort(host) && (hasLocalOrProxyLikeHost(host) || hasNetworkErrorContext(message, offset));
}
__name(shouldRedactTokenOnlyCredential, "shouldRedactTokenOnlyCredential");
function redactProxyCredentials(message) {
  let result = message.replace(/\/\/[^/\s]*@/g, "//<redacted>@");
  result = result.replace(
    /(^|[\s([=:])([^\s/@()[\]=]+@[^@\s/()[\]=]+)/g,
    (match, prefix, candidate, offset, message2) => {
      const atIndex = candidate.indexOf("@");
      const userInfo = candidate.slice(0, atIndex);
      const host = candidate.slice(atIndex + 1);
      if (!userInfo.includes(":") && !shouldRedactTokenOnlyCredential(host, message2, offset)) {
        return match;
      }
      return `${prefix}<redacted>@${host}`;
    }
  );
  return result;
}
__name(redactProxyCredentials, "redactProxyCredentials");
function redactProxyError(error) {
  return redactProxyErrorValue(error, /* @__PURE__ */ new WeakMap());
}
__name(redactProxyError, "redactProxyError");
function redactProxyErrorValue(error, seen) {
  if (typeof error === "string") {
    return redactProxyCredentials(error);
  }
  if (!error || typeof error !== "object") {
    return error;
  }
  if (seen.has(error)) {
    return seen.get(error);
  }
  const errorRecord = error;
  const needsClone = shouldCloneForRedaction(error, errorRecord);
  const redactedMessage = typeof errorRecord.message === "string" ? redactProxyCredentials(errorRecord.message) : void 0;
  const redactedStack = typeof errorRecord.stack === "string" ? redactProxyCredentials(errorRecord.stack) : void 0;
  let redactedCause = errorRecord.cause;
  let redactedErrors = errorRecord.errors;
  if (needsClone) {
    const clone = Object.create(Object.getPrototypeOf(error));
    seen.set(error, clone);
    if (errorRecord.cause !== void 0) {
      redactedCause = redactProxyErrorValue(errorRecord.cause, seen);
    }
    if (errorRecord.errors !== void 0) {
      redactedErrors = redactProxyErrorCollection(errorRecord.errors, seen);
    }
    cloneErrorWithRedactedFields(
      error,
      clone,
      redactedMessage,
      redactedStack,
      redactedCause,
      redactedErrors
    );
    return clone;
  }
  seen.set(error, error);
  try {
    if (redactedMessage !== void 0) {
      errorRecord.message = redactedMessage;
    }
    if (redactedStack !== void 0) {
      errorRecord.stack = redactedStack;
    }
    if (errorRecord.cause !== void 0) {
      redactedCause = redactProxyErrorValue(errorRecord.cause, seen);
      errorRecord.cause = redactedCause;
    }
    if (errorRecord.errors !== void 0) {
      redactedErrors = redactProxyErrorCollection(errorRecord.errors, seen);
      errorRecord.errors = redactedErrors;
    }
    return error;
  } catch {
    const clone = Object.create(Object.getPrototypeOf(error));
    seen.set(error, clone);
    if (errorRecord.cause !== void 0) {
      redactedCause = redactProxyErrorValue(errorRecord.cause, seen);
    }
    if (errorRecord.errors !== void 0) {
      redactedErrors = redactProxyErrorCollection(errorRecord.errors, seen);
    }
    cloneErrorWithRedactedFields(
      error,
      clone,
      redactedMessage,
      redactedStack,
      redactedCause,
      redactedErrors
    );
    return clone;
  }
}
__name(redactProxyErrorValue, "redactProxyErrorValue");
function redactProxyErrorCollection(errors, seen) {
  if (!Array.isArray(errors)) {
    return redactProxyErrorValue(errors, seen);
  }
  if (seen.has(errors)) {
    return seen.get(errors);
  }
  const redactedErrors = [];
  seen.set(errors, redactedErrors);
  for (const error of errors) {
    redactedErrors.push(redactProxyErrorValue(error, seen));
  }
  return redactedErrors;
}
__name(redactProxyErrorCollection, "redactProxyErrorCollection");
function shouldCloneForRedaction(error, errorRecord) {
  return typeof errorRecord.message === "string" && !canAssignProperty(error, "message") || typeof errorRecord.stack === "string" && !canAssignProperty(error, "stack") || errorRecord.cause !== void 0 && !canAssignProperty(error, "cause") || errorRecord.errors !== void 0 && !canAssignProperty(error, "errors");
}
__name(shouldCloneForRedaction, "shouldCloneForRedaction");
function canAssignProperty(target, key) {
  let current = target;
  while (current) {
    const descriptor = Object.getOwnPropertyDescriptor(current, key);
    if (descriptor) {
      if ("writable" in descriptor) {
        return descriptor.writable === true;
      }
      return typeof descriptor.set === "function";
    }
    current = Object.getPrototypeOf(current);
  }
  return Object.isExtensible(target);
}
__name(canAssignProperty, "canAssignProperty");
function cloneErrorWithRedactedFields(error, clone, redactedMessage, redactedStack, redactedCause, redactedErrors) {
  const copiedKeys = /* @__PURE__ */ new Set();
  for (const key of Reflect.ownKeys(error)) {
    const descriptor = Object.getOwnPropertyDescriptor(error, key);
    if (!descriptor) {
      continue;
    }
    copiedKeys.add(key);
    const updatedDescriptor = getRedactedPropertyDescriptor(
      key,
      descriptor,
      redactedMessage,
      redactedStack,
      redactedCause,
      redactedErrors
    );
    try {
      Object.defineProperty(clone, key, updatedDescriptor);
    } catch {
    }
  }
  defineMissingRedactedValue(clone, copiedKeys, "message", redactedMessage);
  defineMissingRedactedValue(clone, copiedKeys, "stack", redactedStack);
  defineMissingRedactedValue(clone, copiedKeys, "cause", redactedCause);
  defineMissingRedactedValue(clone, copiedKeys, "errors", redactedErrors);
}
__name(cloneErrorWithRedactedFields, "cloneErrorWithRedactedFields");
function getRedactedPropertyDescriptor(key, descriptor, redactedMessage, redactedStack, redactedCause, redactedErrors) {
  const redactedValue = key === "message" ? redactedMessage : key === "stack" ? redactedStack : key === "cause" ? redactedCause : key === "errors" ? redactedErrors : void 0;
  if (redactedValue === void 0) {
    return { ...descriptor };
  }
  if ("value" in descriptor) {
    return { ...descriptor, value: redactedValue };
  }
  return {
    configurable: descriptor.configurable,
    enumerable: descriptor.enumerable,
    value: redactedValue,
    writable: true
  };
}
__name(getRedactedPropertyDescriptor, "getRedactedPropertyDescriptor");
function defineMissingRedactedValue(target, copiedKeys, key, value) {
  if (value === void 0 || copiedKeys.has(key)) {
    return;
  }
  try {
    Object.defineProperty(target, key, {
      configurable: true,
      enumerable: false,
      value,
      writable: true
    });
  } catch {
  }
}
__name(defineMissingRedactedValue, "defineMissingRedactedValue");
function recordProxyFailure(hostname) {
  const failureCount = (proxyFailureCounts.get(hostname) ?? 0) + 1;
  proxyFailureCounts.set(hostname, failureCount);
  return failureCount;
}
__name(recordProxyFailure, "recordProxyFailure");
function buildFetchOptionsWithDispatcher(sdkType, proxyUrl) {
  if (!proxyUrl) {
    return NO_DISPATCHER_FALLBACK[sdkType];
  }
  try {
    const dispatcher = getOrCreateSharedDispatcher(proxyUrl);
    return { fetchOptions: { dispatcher }, fetch: import_undici.fetch };
  } catch (error) {
    const hostname = extractHostnameFromProxyUrl(proxyUrl);
    const failureCount = recordProxyFailure(hostname);
    const failureLabel = failureCount === 1 ? "first failure" : `failure #${failureCount}`;
    const errorMessage = error instanceof Error ? error.message : String(error);
    const redactedMessage = redactProxyCredentials(errorMessage);
    const logMessage = `Failed to create proxy dispatcher for ${hostname} (${failureLabel}), falling back to direct connection: ${redactedMessage}`;
    debugLogger.warn(logMessage);
    console.error(`[RUNTIME_FETCH] ${logMessage}`);
    return NO_DISPATCHER_FALLBACK[sdkType];
  }
}
__name(buildFetchOptionsWithDispatcher, "buildFetchOptionsWithDispatcher");

// packages/core/src/utils/request-tokenizer/textTokenizer.ts
init_esbuild_shims();
var TextTokenizer = class {
  static {
    __name(this, "TextTokenizer");
  }
  /**
   * Calculate tokens for text content
   *
   * @param text - The text to estimate tokens for
   * @returns The estimated token count
   */
  async calculateTokens(text) {
    return this.calculateTokensSync(text);
  }
  /**
   * Calculate tokens for multiple text strings
   *
   * @param texts - Array of text strings to estimate tokens for
   * @returns Array of token counts corresponding to each input text
   */
  async calculateTokensBatch(texts) {
    return texts.map((text) => this.calculateTokensSync(text));
  }
  calculateTokensSync(text) {
    if (!text || text.length === 0) {
      return 0;
    }
    let asciiChars = 0;
    let nonAsciiChars = 0;
    for (let i = 0; i < text.length; i++) {
      const charCode = text.charCodeAt(i);
      if (charCode < 128) {
        asciiChars++;
      } else {
        nonAsciiChars++;
      }
    }
    const tokens = asciiChars / 4 + nonAsciiChars * 1.1;
    return Math.ceil(tokens);
  }
};

// packages/core/src/utils/request-tokenizer/supportedImageFormats.ts
init_esbuild_shims();
var SUPPORTED_IMAGE_MIME_TYPES = [
  "image/bmp",
  "image/jpeg",
  "image/jpg",
  // Alternative MIME type for JPEG
  "image/png",
  "image/tiff",
  "image/webp",
  "image/heic"
];
function isSupportedImageMimeType(mimeType) {
  return SUPPORTED_IMAGE_MIME_TYPES.includes(
    mimeType
  );
}
__name(isSupportedImageMimeType, "isSupportedImageMimeType");
function getSupportedImageFormatsString() {
  return SUPPORTED_IMAGE_MIME_TYPES.map(
    (type) => type.replace("image/", "").toUpperCase()
  ).join(", ");
}
__name(getSupportedImageFormatsString, "getSupportedImageFormatsString");
function getUnsupportedImageFormatWarning() {
  return `Only the following image formats are supported: ${getSupportedImageFormatsString()}. Other formats may not work as expected.`;
}
__name(getUnsupportedImageFormatWarning, "getUnsupportedImageFormatWarning");

export {
  detectRuntime,
  buildRuntimeFetchOptions,
  getOrCreateSharedDispatcher,
  redactProxyCredentials,
  redactProxyError,
  TextTokenizer,
  SUPPORTED_IMAGE_MIME_TYPES,
  isSupportedImageMimeType,
  getSupportedImageFormatsString,
  getUnsupportedImageFormatWarning
};
/**
 * @license
 * Copyright 2025 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @license
 * Copyright 2025 Qwen
 * SPDX-License-Identifier: Apache-2.0
 */
