// @bun
import {
  getProxyFetchOptions,
  init_proxy
} from "./chunk-n58eyfnk.js";
import {
  init_providerRegistry,
  resolveAPIKey,
  resolveProvider
} from "./chunk-smkp5pcr.js";
import"./chunk-nxsh6de2.js";
import"./chunk-fbv4apne.js";
import"./chunk-3r24h7t6.js";
import"./chunk-qqfa0dqg.js";
import"./chunk-hqmz36b3.js";
import"./chunk-4g3v8y12.js";
import"./chunk-7739pg2c.js";
import"./chunk-xszk7n10.js";
import"./chunk-sdj9b9wh.js";
import {
  __esm
} from "./chunk-qp2qdcda.js";

// src/services/api/openaiAdapter.ts
import { createHash } from "crypto";
function getOpenAIConfig() {
  const resolved = resolveProvider();
  if (resolved) {
    const { config } = resolved;
    return {
      apiKey: resolveAPIKey(config),
      baseURL: process.env.OPENAI_BASE_URL || config.baseURL,
      model: process.env.OPENAI_MODEL || config.defaultModel
    };
  }
  return {
    apiKey: process.env.OPENAI_API_KEY || "",
    baseURL: process.env.OPENAI_BASE_URL || "https://api.openai.com/v1",
    model: process.env.OPENAI_MODEL || "gpt-4o"
  };
}
function convertMessages(system, messages) {
  const result = [];
  if (system) {
    let sysText = "";
    if (typeof system === "string") {
      sysText = system;
    } else if (Array.isArray(system)) {
      sysText = system.map((b) => typeof b === "string" ? b : b?.text || "").filter(Boolean).join(`
`);
    }
    if (sysText) {
      const maxLen = 8000;
      if (sysText.length > maxLen) {
        sysText = sysText.slice(0, maxLen) + `

[System prompt truncated]`;
      }
      result.push({ role: "system", content: sysText });
    }
  }
  for (const msg of messages) {
    const m = msg;
    if (!m || !m.role)
      continue;
    if (typeof m.content === "string") {
      result.push({ role: m.role === "assistant" ? "assistant" : "user", content: m.content });
      continue;
    }
    if (!Array.isArray(m.content))
      continue;
    if (m.role === "assistant") {
      const textParts = [];
      const toolCalls = [];
      for (const block of m.content) {
        if (!block)
          continue;
        if (block.type === "text" && block.text) {
          textParts.push(block.text);
        } else if (block.type === "tool_use") {
          toolCalls.push({
            id: block.id || `toolu_${Date.now()}`,
            type: "function",
            function: {
              name: block.name,
              arguments: typeof block.input === "string" ? block.input : JSON.stringify(block.input || {})
            }
          });
        }
      }
      const assistantMsg = { role: "assistant" };
      const text = textParts.join(`
`);
      if (text)
        assistantMsg.content = text;
      else if (toolCalls.length > 0)
        assistantMsg.content = null;
      if (toolCalls.length > 0)
        assistantMsg.tool_calls = toolCalls;
      if (text || toolCalls.length > 0)
        result.push(assistantMsg);
    } else {
      const textParts = [];
      const toolResults = [];
      for (const block of m.content) {
        if (!block)
          continue;
        if (typeof block === "string") {
          textParts.push(block);
        } else if (block.type === "text") {
          textParts.push(block.text || "");
        } else if (block.type === "tool_result") {
          const resultContent = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map((c) => c.text || JSON.stringify(c) || "").join(`
`) : JSON.stringify(block.content || "");
          toolResults.push({
            tool_call_id: block.tool_use_id || "unknown",
            content: block.is_error ? `[ERROR] ${resultContent}` : resultContent
          });
        } else if (block.type === "image") {
          textParts.push("[Image content]");
        }
      }
      for (const tr of toolResults) {
        result.push({
          role: "tool",
          tool_call_id: tr.tool_call_id,
          content: tr.content
        });
      }
      const text = textParts.join(`
`).trim();
      if (text) {
        result.push({ role: "user", content: text });
      }
    }
  }
  return result;
}
function convertTools(tools) {
  if (!tools || tools.length === 0)
    return;
  const filtered = tools.filter((tool) => {
    if (SKIP_TOOLS.has(tool.name))
      return false;
    if (TIER1_TOOLS.has(tool.name))
      return true;
    if (TIER2_TOOLS.has(tool.name))
      return true;
    if (tool.name?.startsWith("mcp__"))
      return true;
    return false;
  });
  if (filtered.length === 0)
    return;
  return filtered.map((tool) => ({
    type: "function",
    function: {
      name: tool.name,
      description: (tool.description || "").slice(0, 800),
      parameters: tool.input_schema || {}
    }
  }));
}
async function* openaiStreamToAnthropicEvents(response, model) {
  yield {
    type: "message_start",
    message: {
      id: `msg_openai_${Date.now()}`,
      type: "message",
      role: "assistant",
      content: [],
      model,
      stop_reason: null,
      stop_sequence: null,
      usage: { input_tokens: 0, output_tokens: 0 }
    }
  };
  let textBlockStarted = false;
  let textBlockIndex = 0;
  let toolCallBlocks = new Map;
  let thinkingBlockStarted = false;
  let thinkingBlockIndex = -1;
  let nextBlockIndex = 0;
  let outputTokens = 0;
  let inputTokens = 0;
  let hasToolCalls = false;
  const reader = response.body?.getReader();
  if (!reader)
    return;
  const decoder = new TextDecoder;
  let buffer = "";
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done)
        break;
      buffer += decoder.decode(value, { stream: true });
      const lines = buffer.split(`
`);
      buffer = lines.pop() || "";
      for (const line of lines) {
        const trimmed = line.trim();
        if (!trimmed || trimmed === "data: [DONE]")
          continue;
        if (!trimmed.startsWith("data: "))
          continue;
        let chunk;
        try {
          chunk = JSON.parse(trimmed.slice(6));
        } catch {
          continue;
        }
        if (chunk.usage) {
          inputTokens = chunk.usage.prompt_tokens || 0;
          outputTokens = chunk.usage.completion_tokens || 0;
        }
        for (const choice of chunk.choices) {
          const delta = choice.delta;
          const thinkingText = delta.reasoning_content || delta.reasoning;
          if (thinkingText) {
            if (!thinkingBlockStarted) {
              thinkingBlockIndex = nextBlockIndex++;
              thinkingBlockStarted = true;
              yield {
                type: "content_block_start",
                index: thinkingBlockIndex,
                content_block: { type: "thinking", thinking: "", signature: "" }
              };
            }
            yield {
              type: "content_block_delta",
              index: thinkingBlockIndex,
              delta: { type: "thinking_delta", thinking: thinkingText }
            };
          }
          if (delta.content && delta.content.length > 0) {
            if (thinkingBlockStarted && !textBlockStarted) {
              yield {
                type: "content_block_stop",
                index: thinkingBlockIndex
              };
              thinkingBlockStarted = false;
            }
            if (!textBlockStarted) {
              textBlockIndex = nextBlockIndex++;
              textBlockStarted = true;
              yield {
                type: "content_block_start",
                index: textBlockIndex,
                content_block: { type: "text", text: "" }
              };
            }
            yield {
              type: "content_block_delta",
              index: textBlockIndex,
              delta: { type: "text_delta", text: delta.content }
            };
            outputTokens++;
          }
          if (delta.tool_calls) {
            for (const tc of delta.tool_calls) {
              if (!toolCallBlocks.has(tc.index)) {
                if (textBlockStarted) {
                  yield { type: "content_block_stop", index: textBlockIndex };
                  textBlockStarted = false;
                }
                if (thinkingBlockStarted) {
                  yield { type: "content_block_stop", index: thinkingBlockIndex };
                  thinkingBlockStarted = false;
                }
                const blockIdx = nextBlockIndex++;
                const toolId = tc.id || `toolu_openai_${Date.now()}_${tc.index}`;
                const toolName = tc.function?.name || "";
                toolCallBlocks.set(tc.index, { id: toolId, name: toolName, argsBuf: "", blockIndex: blockIdx });
                yield {
                  type: "content_block_start",
                  index: blockIdx,
                  content_block: {
                    type: "tool_use",
                    id: toolId,
                    name: toolName,
                    input: {}
                  }
                };
              }
              const block = toolCallBlocks.get(tc.index);
              if (tc.function?.arguments) {
                block.argsBuf += tc.function.arguments;
                yield {
                  type: "content_block_delta",
                  index: block.blockIndex,
                  delta: {
                    type: "input_json_delta",
                    partial_json: tc.function.arguments
                  }
                };
              }
            }
          }
          if (choice.finish_reason) {
            if (thinkingBlockStarted) {
              yield { type: "content_block_stop", index: thinkingBlockIndex };
              thinkingBlockStarted = false;
            }
            if (textBlockStarted) {
              yield { type: "content_block_stop", index: textBlockIndex };
              textBlockStarted = false;
            }
            for (const [, tcBlock] of toolCallBlocks) {
              yield { type: "content_block_stop", index: tcBlock.blockIndex };
            }
            if (choice.finish_reason === "tool_calls") {
              hasToolCalls = true;
            }
          }
        }
      }
    }
  } finally {
    reader.releaseLock();
  }
  yield {
    type: "message_delta",
    delta: { stop_reason: hasToolCalls ? "tool_use" : "end_turn", stop_sequence: null },
    usage: { output_tokens: outputTokens }
  };
  yield {
    type: "message_stop"
  };
}
function hashKey(key) {
  return createHash("sha256").update(key).digest("hex");
}
function verifyOllamaLicense() {
  const userSetBaseURL = process.env.OPENAI_BASE_URL;
  const userSetProvider = process.env.PROVIDER;
  if (userSetBaseURL)
    return;
  if (userSetProvider && userSetProvider.toLowerCase() !== "ollama")
    return;
  if (process.env.OPENAI_API_KEY || process.env.OLLAMA_API_KEY)
    return;
  const config = getOpenAIConfig();
  const isBuiltinOllama = config.baseURL.includes("218.201.19.105:11434") || config.baseURL.includes("localhost:11434") || config.baseURL.includes("127.0.0.1:11434");
  if (!isBuiltinOllama)
    return;
  const licenseKey = process.env.JIALING_LICENSE_KEY?.trim();
  if (!licenseKey) {
    throw new Error(`
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
` + `\u2551  \u5609\u9675\u6C5F-code Ollama \u672C\u5730\u6A21\u5F0F\u9700\u8981\u6388\u6743\u5BC6\u94A5                  \u2551
` + `\u2551                                                          \u2551
` + `\u2551  \u8BF7\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF:                                          \u2551
` + `\u2551    export JIALING_LICENSE_KEY="\u4F60\u7684\u5BC6\u94A5"                   \u2551
` + `\u2551                                                          \u2551
` + `\u2551  \u83B7\u53D6\u5BC6\u94A5\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458                                      \u2551
` + `\u2551                                                          \u2551
` + `\u2551  \u4F7F\u7528\u5176\u4ED6\u5927\u6A21\u578B\u5382\u5546\u4E0D\u53D7\u6B64\u9650\u5236:                              \u2551
` + `\u2551    export DEEPSEEK_API_KEY=sk-xxx  (DeepSeek)             \u2551
` + `\u2551    export OPENAI_API_KEY=sk-xxx    (OpenAI)               \u2551
` + `\u2551    export QWEN_API_KEY=sk-xxx      (\u901A\u4E49\u5343\u95EE)              \u2551
` + `\u2551    ... \u652F\u6301 22+ \u5382\u5546\uFF0C\u8BE6\u89C1\u6587\u6863                             \u2551
` + `\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
`);
  }
  if (!OLLAMA_LICENSE_HASHES.has(hashKey(licenseKey))) {
    throw new Error(`
[\u5609\u9675\u6C5F-code] \u5BC6\u94A5\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5 JIALING_LICENSE_KEY \u662F\u5426\u6B63\u786E\u3002
`);
  }
}
function createOpenAIAdapterClient(options) {
  verifyOllamaLicense();
  const config = getOpenAIConfig();
  const client = {
    beta: {
      messages: {
        create: (params, requestOptions) => {
          const doFetch = async () => {
            const model = params.model || config.model;
            const openaiMessages = convertMessages(params.system, params.messages);
            const openaiTools = convertTools(params.tools || []);
            const isOllama = config.baseURL.includes("localhost:11434") || config.baseURL.includes("127.0.0.1:11434") || config.baseURL.includes("218.201.19.105:11434") || process.env.PROVIDER === "ollama";
            const body = {
              model,
              messages: openaiMessages,
              stream: true,
              ...!isOllama && { stream_options: { include_usage: true } },
              max_tokens: params.max_tokens || 16384
            };
            if (params.temperature !== undefined) {
              body.temperature = params.temperature;
            }
            if (openaiTools && openaiTools.length > 0) {
              body.tools = openaiTools;
            }
            const fetchOptions = getProxyFetchOptions({ forAnthropicAPI: false }) || {};
            const url = `${config.baseURL.replace(/\/+$/, "")}/chat/completions`;
            const headers = {
              "Content-Type": "application/json",
              ...process.env.OPENAI_CUSTOM_HEADERS ? parseCustomHeaders(process.env.OPENAI_CUSTOM_HEADERS) : {}
            };
            if (config.apiKey && config.apiKey !== "ollama") {
              headers["Authorization"] = `Bearer ${config.apiKey}`;
            }
            const response = await fetch(url, {
              method: "POST",
              headers,
              body: JSON.stringify(body),
              signal: requestOptions?.signal,
              ...fetchOptions
            });
            if (!response.ok) {
              const errorText = await response.text().catch(() => "Unknown error");
              throw new Error(`OpenAI API error (${response.status}): ${errorText}`);
            }
            const stream = openaiStreamToAnthropicEvents(response, model);
            return { stream, response };
          };
          const resultPromise = doFetch();
          return {
            withResponse: () => resultPromise.then(({ stream, response }) => ({
              data: stream,
              response,
              request_id: response.headers.get("x-request-id") || `openai-${Date.now()}`
            })),
            then: (resolve, reject) => resultPromise.then(({ stream }) => stream).then(resolve, reject)
          };
        }
      }
    },
    messages: {
      create: async () => {
        throw new Error("Use beta.messages.create for OpenAI adapter");
      }
    }
  };
  return client;
}
function parseCustomHeaders(headerStr) {
  const headers = {};
  for (const line of headerStr.split(/\n|\r\n/)) {
    const idx = line.indexOf(":");
    if (idx === -1)
      continue;
    const name = line.slice(0, idx).trim();
    const value = line.slice(idx + 1).trim();
    if (name)
      headers[name] = value;
  }
  return headers;
}
var TIER1_TOOLS, TIER2_TOOLS, SKIP_TOOLS, OLLAMA_LICENSE_HASHES;
var init_openaiAdapter = __esm(() => {
  init_proxy();
  init_providerRegistry();
  TIER1_TOOLS = new Set([
    "Bash",
    "Read",
    "Write",
    "Edit",
    "Glob",
    "Grep"
  ]);
  TIER2_TOOLS = new Set([
    "WebFetch",
    "WebSearch",
    "NotebookEdit",
    "Agent"
  ]);
  SKIP_TOOLS = new Set([
    "EnterPlanMode",
    "ExitPlanMode",
    "EnterWorktree",
    "ExitWorktree",
    "TodoWrite",
    "Brief",
    "TaskOutput",
    "TaskStop",
    "TaskCreate",
    "TaskGet",
    "TaskUpdate",
    "TaskList",
    "TeamCreate",
    "TeamDelete",
    "ToolSearch",
    "SendMessage",
    "AskUserQuestion",
    "Skill",
    "ListMcpResources",
    "ReadMcpResource",
    "SyntheticOutput",
    "CronCreate",
    "CronDelete",
    "CronList"
  ]);
  OLLAMA_LICENSE_HASHES = new Set([
    "2352f11c7b38404b2ab5a135b3c429199a5a0ff7c04349c9179b3f58265f6b3a"
  ]);
});
init_openaiAdapter();

export {
  getOpenAIConfig,
  createOpenAIAdapterClient
};
