// @bun
import {
  OpenAI,
  init_openai
} from "./chunk-cbcxbbe6.js";
import {
  TOOL_SEARCH_TOOL_NAME,
  addToTotalSessionCost,
  convertMessagesToLangfuse,
  convertOutputToLangfuse,
  convertToolsToLangfuse,
  createAssistantAPIErrorMessage,
  createUserMessage,
  extractDiscoveredToolNames,
  formatDeferredToolLine,
  getEmptyToolPermissionContext,
  init_Tool,
  init_api,
  init_convert,
  init_cost_tracker,
  init_messages1 as init_messages,
  init_prompt10 as init_prompt,
  init_toolSearch,
  init_tracing,
  isDeferredTool,
  isDeferredToolsDeltaEnabled,
  isToolSearchEnabled,
  normalizeContentFromAPI,
  normalizeMessagesForAPI,
  recordLLMObservation,
  toolMatchesName,
  toolToAPISchema
} from "./chunk-421yegj3.js";
import"./chunk-aaxz8a5g.js";
import"./chunk-2kcgxnvp.js";
import"./chunk-14p6wvsq.js";
import"./chunk-6s0q1s5r.js";
import"./chunk-0cpg8qh8.js";
import {
  adaptOpenAIStreamToAnthropic,
  anthropicMessagesToOpenAI,
  anthropicToolChoiceToOpenAI,
  anthropicToolsToOpenAI,
  init_src,
  resolveOpenAIModel
} from "./chunk-9phn5khx.js";
import"./chunk-vk9xcryd.js";
import"./chunk-9a9g5hbj.js";
import"./chunk-ptxteaeh.js";
import"./chunk-7fcmqvbz.js";
import {
  init_store,
  updateProviderBuckets
} from "./chunk-rgyzsbs3.js";
import"./chunk-q3b4n194.js";
import"./chunk-zaqfb3tz.js";
import"./chunk-6hzx0kqr.js";
import"./chunk-71sdcaq6.js";
import"./chunk-9hn8e6h1.js";
import"./chunk-dxa3y9vh.js";
import"./chunk-gjvhjywj.js";
import"./chunk-1w20m7gw.js";
import"./chunk-3gam18xn.js";
import"./chunk-rpmntgyh.js";
import"./chunk-24kv69g3.js";
import"./chunk-tzcrwnrf.js";
import"./chunk-k7xszak2.js";
import"./chunk-ztmb7geg.js";
import"./chunk-tbdkekz3.js";
import"./chunk-65zbgg1n.js";
import"./chunk-4spgkgr3.js";
import"./chunk-60fkafk2.js";
import"./chunk-h5zz0vxy.js";
import"./chunk-6hygvrhn.js";
import"./chunk-7tfdhkpy.js";
import"./chunk-8gv2pjby.js";
import"./chunk-pn23dh3d.js";
import"./chunk-rpdh02rm.js";
import"./chunk-j1wktfe2.js";
import"./chunk-fjtzfz1t.js";
import"./chunk-6hr7742d.js";
import"./chunk-xyg1sk2w.js";
import"./chunk-935nrvdb.js";
import"./chunk-8zz4z1q3.js";
import"./chunk-hem4f4gz.js";
import"./chunk-hqxp6b72.js";
import"./chunk-ccw8pse0.js";
import"./chunk-wsnxtggw.js";
import"./chunk-k8nwt8yq.js";
import"./chunk-vxbjzggp.js";
import"./chunk-d6h68rz1.js";
import"./chunk-8yvsnrkr.js";
import"./chunk-5mmhfbxb.js";
import {
  calculateUSDCost,
  getModelMaxOutputTokens,
  init_context,
  init_modelCost
} from "./chunk-s2t5anwv.js";
import"./chunk-ga1jkyqy.js";
import"./chunk-9hbhydvp.js";
import {
  getProxyFetchOptions,
  init_proxy
} from "./chunk-ck9r8hpf.js";
import"./chunk-k7hexw3v.js";
import"./chunk-trqrj23e.js";
import"./chunk-za3k6h2h.js";
import"./chunk-8kf8h7xf.js";
import"./chunk-bgan4cpf.js";
import"./chunk-jmv7k0jn.js";
import"./chunk-hjxqmtg5.js";
import"./chunk-bzyzrq0k.js";
import"./chunk-vwenx8ke.js";
import"./chunk-q2h79ncs.js";
import"./chunk-v4ypszbb.js";
import"./chunk-qfsn720k.js";
import"./chunk-7qx3xhv3.js";
import"./chunk-j9475b46.js";
import"./chunk-fdwabr8p.js";
import"./chunk-e4dsy4g1.js";
import"./chunk-326zehp8.js";
import"./chunk-kc67kt75.js";
import"./chunk-40t1d75v.js";
import"./chunk-dbts5q5p.js";
import"./chunk-e3abfxpy.js";
import"./chunk-q44zc68f.js";
import"./chunk-fejeqe61.js";
import"./chunk-q1vrhh0q.js";
import"./chunk-hn4w9pkj.js";
import"./chunk-2g0ytd9d.js";
import"./chunk-de0qnnf7.js";
import"./chunk-j1mep9ck.js";
import"./chunk-6x35ffpx.js";
import"./chunk-1zbwhcbt.js";
import"./chunk-92bjkrf2.js";
import"./chunk-10k5jfc5.js";
import"./chunk-n9g24mwe.js";
import"./chunk-e3j7m7k2.js";
import"./chunk-hzmzwte2.js";
import"./chunk-pdvg91cg.js";
import"./chunk-c696122m.js";
import"./chunk-xbj5keyy.js";
import"./chunk-c1yc761e.js";
import"./chunk-c5g9shkw.js";
import"./chunk-aeysytks.js";
import {
  init_debug,
  init_envUtils,
  isEnvDefinedFalsy,
  isEnvTruthy,
  logForDebugging
} from "./chunk-s3hafnk3.js";
import"./chunk-kb3758f7.js";
import"./chunk-9h9k5vz3.js";
import"./chunk-xmpgmeb8.js";
import"./chunk-2kz09j2s.js";
import"./chunk-c0k7b0jw.js";
import"./chunk-pecy49yr.js";
import"./chunk-azbab59e.js";
import"./chunk-3nk9q8dr.js";
import {
  __esm
} from "./chunk-hhsxm2yr.js";

// src/services/providerUsage/adapters/openai.ts
function parseResetAt(value) {
  if (!value)
    return 0;
  let seconds = 0;
  const re = /(\d+(?:\.\d+)?)(ms|s|m|h|d)/g;
  let match;
  while ((match = re.exec(value)) !== null) {
    const n = Number(match[1]);
    const unit = match[2];
    switch (unit) {
      case "ms":
        seconds += n / 1000;
        break;
      case "s":
        seconds += n;
        break;
      case "m":
        seconds += n * 60;
        break;
      case "h":
        seconds += n * 3600;
        break;
      case "d":
        seconds += n * 86400;
        break;
    }
  }
  if (seconds === 0) {
    const n = Number(value);
    if (Number.isFinite(n))
      seconds = n;
  }
  if (seconds <= 0)
    return 0;
  return Math.floor(Date.now() / 1000) + seconds;
}
function computeUtilization(remaining, limit) {
  if (remaining === null || limit === null)
    return null;
  const r = Number(remaining);
  const l = Number(limit);
  if (!Number.isFinite(r) || !Number.isFinite(l) || l <= 0)
    return null;
  const used = Math.max(0, l - r);
  return Math.min(1, Math.max(0, used / l));
}
var openaiAdapter;
var init_openai2 = __esm(() => {
  openaiAdapter = {
    providerId: "openai",
    parseHeaders(headers) {
      const buckets = [];
      const reqUtil = computeUtilization(headers.get("x-ratelimit-remaining-requests"), headers.get("x-ratelimit-limit-requests"));
      if (reqUtil !== null) {
        buckets.push({
          kind: "requests",
          label: "RPM",
          utilization: reqUtil,
          resetsAt: parseResetAt(headers.get("x-ratelimit-reset-requests")) || undefined
        });
      }
      const tokUtil = computeUtilization(headers.get("x-ratelimit-remaining-tokens"), headers.get("x-ratelimit-limit-tokens"));
      if (tokUtil !== null) {
        buckets.push({
          kind: "tokens",
          label: "TPM",
          utilization: tokUtil,
          resetsAt: parseResetAt(headers.get("x-ratelimit-reset-tokens")) || undefined
        });
      }
      return buckets;
    }
  };
});

// src/services/api/openai/client.ts
function wrapFetchForUsage(base) {
  const wrapped = async (...args) => {
    const res = await base(...args);
    try {
      updateProviderBuckets("openai", openaiAdapter.parseHeaders(res.headers));
    } catch {}
    return res;
  };
  return wrapped;
}
function getOpenAIClient(options) {
  if (cachedClient)
    return cachedClient;
  const apiKey = process.env.OPENAI_API_KEY || process.env.REDSCOPE_AUTH_TOKEN || process.env.REDSCOPE_API_KEY || "";
  const baseURL = process.env.OPENAI_BASE_URL || process.env.REDSCOPE_BASE_URL;
  const baseFetch = options?.fetchOverride ?? globalThis.fetch;
  const wrappedFetch = wrapFetchForUsage(baseFetch);
  const client = new OpenAI({
    apiKey,
    ...baseURL && { baseURL },
    maxRetries: options?.maxRetries ?? 0,
    timeout: parseInt(process.env.API_TIMEOUT_MS || String(600 * 1000), 10),
    dangerouslyAllowBrowser: true,
    ...process.env.OPENAI_ORG_ID && {
      organization: process.env.OPENAI_ORG_ID
    },
    ...process.env.OPENAI_PROJECT_ID && {
      project: process.env.OPENAI_PROJECT_ID
    },
    fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }),
    fetch: wrappedFetch
  });
  if (!options?.fetchOverride) {
    cachedClient = client;
  }
  return client;
}
var cachedClient = null;
var init_client = __esm(() => {
  init_openai();
  init_openai2();
  init_store();
  init_proxy();
});

// src/services/api/openai/requestBody.ts
function isOpenAIThinkingEnabled(model) {
  if (isEnvDefinedFalsy(process.env.OPENAI_ENABLE_THINKING))
    return false;
  if (isEnvTruthy(process.env.OPENAI_ENABLE_THINKING))
    return true;
  const modelLower = model.toLowerCase();
  return modelLower.includes("deepseek");
}
function resolveOpenAIMaxTokens(upperLimit, maxOutputTokensOverride) {
  return maxOutputTokensOverride ?? (process.env.OPENAI_MAX_TOKENS ? parseInt(process.env.OPENAI_MAX_TOKENS, 10) || undefined : undefined) ?? (process.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS ? parseInt(process.env.CLAUDE_CODE_MAX_OUTPUT_TOKENS, 10) || undefined : undefined) ?? upperLimit;
}
function buildOpenAIRequestBody(params) {
  const {
    model,
    messages,
    tools,
    toolChoice,
    enableThinking,
    maxTokens,
    temperatureOverride
  } = params;
  return {
    model,
    messages,
    max_tokens: maxTokens,
    ...tools.length > 0 && {
      tools,
      ...toolChoice && { tool_choice: toolChoice }
    },
    stream: true,
    stream_options: { include_usage: true },
    ...enableThinking && {
      thinking: { type: "enabled" },
      enable_thinking: true,
      chat_template_kwargs: { thinking: true }
    },
    ...!enableThinking && temperatureOverride !== undefined && {
      temperature: temperatureOverride
    }
  };
}
var init_requestBody = __esm(() => {
  init_envUtils();
});

// src/services/api/openai/index.ts
import { randomUUID } from "crypto";
function prependDeferredToolListIfNeeded(messages, tools, deferredToolNames, useToolSearch) {
  if (!useToolSearch || isDeferredToolsDeltaEnabled())
    return messages;
  const deferredToolList = tools.filter((tool) => deferredToolNames.has(tool.name)).map(formatDeferredToolLine).sort().join(`
`);
  if (!deferredToolList)
    return messages;
  return [
    createUserMessage({
      content: `<available-deferred-tools>
${deferredToolList}
</available-deferred-tools>`,
      isMeta: true
    }),
    ...messages
  ];
}
function isOpenAIConvertibleMessage(msg) {
  return msg.type === "assistant" || msg.type === "user";
}
function assembleFinalAssistantOutputs(params) {
  const {
    partialMessage,
    contentBlocks,
    tools,
    agentId,
    usage,
    stopReason,
    maxTokens
  } = params;
  const outputs = [];
  const allBlocks = Object.keys(contentBlocks).sort((a, b) => Number(a) - Number(b)).map((k) => contentBlocks[Number(k)]).filter(Boolean);
  if (allBlocks.length > 0) {
    outputs.push({
      message: {
        ...partialMessage,
        content: normalizeContentFromAPI(allBlocks, tools, agentId),
        usage,
        stop_reason: stopReason,
        stop_sequence: null
      },
      requestId: undefined,
      type: "assistant",
      uuid: randomUUID(),
      timestamp: new Date().toISOString()
    });
  }
  if (stopReason === "max_tokens") {
    outputs.push(createAssistantAPIErrorMessage({
      content: `Output truncated: response exceeded the ${maxTokens} token limit. ` + `Set OPENAI_MAX_TOKENS or CLAUDE_CODE_MAX_OUTPUT_TOKENS to override.`,
      apiError: "max_output_tokens",
      error: "max_output_tokens"
    }));
  }
  return outputs;
}
async function* queryModelOpenAI(messages, systemPrompt, tools, signal, options) {
  try {
    const openaiModel = resolveOpenAIModel(options.model);
    const messagesForAPI = normalizeMessagesForAPI(messages, tools);
    const useToolSearch = await isToolSearchEnabled(options.model, tools, options.getToolPermissionContext || (async () => getEmptyToolPermissionContext()), options.agents || [], options.querySource);
    const deferredToolNames = new Set;
    if (useToolSearch) {
      for (const t of tools) {
        if (isDeferredTool(t))
          deferredToolNames.add(t.name);
      }
    }
    let filteredTools = tools;
    if (useToolSearch && deferredToolNames.size > 0) {
      const discoveredToolNames = extractDiscoveredToolNames(messages);
      filteredTools = tools.filter((tool) => {
        if (!deferredToolNames.has(tool.name))
          return true;
        if (toolMatchesName(tool, TOOL_SEARCH_TOOL_NAME))
          return true;
        return discoveredToolNames.has(tool.name);
      });
    }
    const toolSchemas = await Promise.all(filteredTools.map((tool) => toolToAPISchema(tool, {
      getToolPermissionContext: options.getToolPermissionContext,
      tools,
      agents: options.agents,
      allowedAgentTypes: options.allowedAgentTypes,
      model: options.model,
      deferLoading: useToolSearch && deferredToolNames.has(tool.name)
    })));
    const standardTools = toolSchemas.filter((t) => {
      const anyT = t;
      return anyT.type !== "advisor_20260301" && anyT.type !== "computer_20250124";
    });
    const enableThinking = isOpenAIThinkingEnabled(openaiModel);
    const openAIConvertibleMessages = messagesForAPI.filter(isOpenAIConvertibleMessage);
    const messagesWithDeferredToolList = prependDeferredToolListIfNeeded(openAIConvertibleMessages, tools, deferredToolNames, useToolSearch);
    const openaiMessages = anthropicMessagesToOpenAI(messagesWithDeferredToolList, systemPrompt, { enableThinking });
    const openaiTools = anthropicToolsToOpenAI(standardTools);
    const openaiToolChoice = anthropicToolChoiceToOpenAI(options.toolChoice);
    if (useToolSearch) {
      const includedDeferredTools = filteredTools.filter((t) => deferredToolNames.has(t.name)).length;
      logForDebugging(`[OpenAI] Tool search enabled: ${includedDeferredTools}/${deferredToolNames.size} deferred tools included, total tools=${openaiTools.length}`);
    } else {
      logForDebugging(`[OpenAI] Tool search disabled, total tools=${openaiTools.length}`);
    }
    const { upperLimit } = getModelMaxOutputTokens(openaiModel);
    const maxTokens = resolveOpenAIMaxTokens(upperLimit, options.maxOutputTokensOverride);
    const client = getOpenAIClient({
      maxRetries: 0,
      fetchOverride: options.fetchOverride,
      source: options.querySource
    });
    logForDebugging(`[OpenAI] Calling model=${openaiModel}, messages=${openaiMessages.length}, tools=${openaiTools.length}, thinking=${enableThinking}`);
    const requestBody = buildOpenAIRequestBody({
      model: openaiModel,
      messages: openaiMessages,
      tools: openaiTools,
      toolChoice: openaiToolChoice,
      enableThinking,
      maxTokens,
      temperatureOverride: options.temperatureOverride
    });
    const stream = await client.chat.completions.create(requestBody, { signal });
    const adaptedStream = adaptOpenAIStreamToAnthropic(stream, openaiModel);
    const contentBlocks = {};
    const collectedMessages = [];
    let partialMessage;
    let stopReason = null;
    let usage = {
      input_tokens: 0,
      output_tokens: 0,
      cache_creation_input_tokens: 0,
      cache_read_input_tokens: 0
    };
    let ttftMs = 0;
    const start = Date.now();
    for await (const event of adaptedStream) {
      switch (event.type) {
        case "message_start": {
          partialMessage = event.message;
          ttftMs = Date.now() - start;
          if (event.message?.usage) {
            usage = {
              ...usage,
              ...event.message.usage
            };
          }
          break;
        }
        case "content_block_start": {
          const idx = event.index;
          const cb = event.content_block;
          if (cb.type === "tool_use") {
            contentBlocks[idx] = { ...cb, input: "" };
          } else if (cb.type === "text") {
            contentBlocks[idx] = { ...cb, text: "" };
          } else if (cb.type === "thinking") {
            contentBlocks[idx] = { ...cb, thinking: "", signature: "" };
          } else {
            contentBlocks[idx] = { ...cb };
          }
          break;
        }
        case "content_block_delta": {
          const idx = event.index;
          const delta = event.delta;
          const block = contentBlocks[idx];
          if (!block)
            break;
          if (delta.type === "text_delta") {
            block.text = (block.text || "") + delta.text;
          } else if (delta.type === "input_json_delta") {
            block.input = (block.input || "") + delta.partial_json;
          } else if (delta.type === "thinking_delta") {
            block.thinking = (block.thinking || "") + delta.thinking;
          } else if (delta.type === "signature_delta") {
            block.signature = delta.signature;
          }
          break;
        }
        case "content_block_stop": {
          break;
        }
        case "message_delta": {
          const deltaUsage = event.usage;
          if (deltaUsage) {
            usage = { ...usage, ...deltaUsage };
          }
          if (event.delta?.stop_reason != null) {
            stopReason = event.delta.stop_reason;
          }
          break;
        }
        case "message_stop": {
          if (partialMessage) {
            for (const output of assembleFinalAssistantOutputs({
              partialMessage,
              contentBlocks,
              tools,
              agentId: options.agentId,
              usage,
              stopReason,
              maxTokens
            })) {
              if (output.type === "assistant") {
                collectedMessages.push(output);
              }
              yield output;
            }
            partialMessage = null;
          }
          if (usage.input_tokens + usage.output_tokens > 0) {
            const costUSD = calculateUSDCost(openaiModel, usage);
            addToTotalSessionCost(costUSD, usage, options.model);
          }
          break;
        }
      }
      yield {
        type: "stream_event",
        event,
        ...event.type === "message_start" ? { ttftMs } : undefined
      };
    }
    recordLLMObservation(options.langfuseTrace ?? null, {
      model: openaiModel,
      provider: "openai",
      input: convertMessagesToLangfuse(openaiMessages),
      output: convertOutputToLangfuse(collectedMessages),
      usage: {
        input_tokens: usage.input_tokens,
        output_tokens: usage.output_tokens,
        cache_creation_input_tokens: usage.cache_creation_input_tokens,
        cache_read_input_tokens: usage.cache_read_input_tokens
      },
      startTime: new Date(start),
      endTime: new Date,
      completionStartTime: ttftMs > 0 ? new Date(start + ttftMs) : undefined,
      tools: convertToolsToLangfuse(toolSchemas),
      ...enableThinking && { thinking: { type: "enabled" } }
    });
    if (partialMessage) {
      for (const output of assembleFinalAssistantOutputs({
        partialMessage,
        contentBlocks,
        tools,
        agentId: options.agentId,
        usage,
        stopReason,
        maxTokens
      })) {
        yield output;
      }
    }
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    logForDebugging(`[OpenAI] Error: ${errorMessage}`, { level: "error" });
    yield createAssistantAPIErrorMessage({
      content: `API Error: ${errorMessage}`,
      apiError: "api_error",
      error: error instanceof Error ? error : new Error(String(error))
    });
  }
}
var init_openai3 = __esm(() => {
  init_client();
  init_src();
  init_messages();
  init_api();
  init_Tool();
  init_debug();
  init_cost_tracker();
  init_modelCost();
  init_requestBody();
  init_tracing();
  init_convert();
  init_context();
  init_messages();
  init_toolSearch();
  init_prompt();
});
init_openai3();

export {
  resolveOpenAIMaxTokens,
  queryModelOpenAI,
  isOpenAIThinkingEnabled,
  buildOpenAIRequestBody
};
