// @bun
var __create = Object.create;
var __getProtoOf = Object.getPrototypeOf;
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __hasOwnProp = Object.prototype.hasOwnProperty;
function __accessProp(key) {
  return this[key];
}
var __toESMCache_node;
var __toESMCache_esm;
var __toESM = (mod, isNodeMode, target) => {
  var canCache = mod != null && typeof mod === "object";
  if (canCache) {
    var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
    var cached = cache.get(mod);
    if (cached)
      return cached;
  }
  target = mod != null ? __create(__getProtoOf(mod)) : {};
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
  for (let key of __getOwnPropNames(mod))
    if (!__hasOwnProp.call(to, key))
      __defProp(to, key, {
        get: __accessProp.bind(mod, key),
        enumerable: true
      });
  if (canCache)
    cache.set(mod, to);
  return to;
};
var __toCommonJS = (from) => {
  var entry = (__moduleCache ??= new WeakMap).get(from), desc;
  if (entry)
    return entry;
  entry = __defProp({}, "__esModule", { value: true });
  if (from && typeof from === "object" || typeof from === "function") {
    for (var key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(entry, key))
        __defProp(entry, key, {
          get: __accessProp.bind(from, key),
          enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
        });
  }
  __moduleCache.set(from, entry);
  return entry;
};
var __moduleCache;
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
var __returnValue = (v) => v;
function __exportSetter(name, newValue) {
  this[name] = __returnValue.bind(null, newValue);
}
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, {
      get: all[name],
      enumerable: true,
      configurable: true,
      set: __exportSetter.bind(all, name)
    });
};
var __legacyDecorateClassTS = function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1;i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __legacyMetadataTS = (k, v) => {
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
    return Reflect.metadata(k, v);
};
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
var __require = import.meta.require;

// src/ai/providers/anthropic.ts
var DEFAULT_BASE_URL = "https://api.anthropic.com";
var API_VERSION = "2023-06-01";
var MAX_TOKENS = 8192;
var EVENT_PREFIX_LENGTH = 7;
var DATA_PREFIX_LENGTH = 6;
var EMPTY_CHUNKS = [];
var isRecord = (val) => typeof val === "object" && val !== null;
var mapContentBlock = (block) => {
  if (block.type === "thinking") {
    return {
      signature: block.signature,
      thinking: block.thinking,
      type: "thinking"
    };
  }
  if (block.type === "image") {
    return {
      source: block.source,
      type: "image"
    };
  }
  if (block.type === "document") {
    return {
      source: block.source,
      type: "document"
    };
  }
  if (block.type === "tool_result") {
    return {
      content: block.content,
      tool_use_id: block.tool_use_id,
      type: "tool_result"
    };
  }
  if (block.type === "tool_use") {
    return {
      id: block.id,
      input: block.input,
      name: block.name,
      type: "tool_use"
    };
  }
  return { text: block.content, type: "text" };
};
var mapMessage = (msg) => ({
  content: typeof msg.content === "string" ? msg.content : msg.content.map(mapContentBlock),
  role: msg.role === "system" ? "user" : msg.role
});
var mapToolDefinition = (tool) => ({
  description: tool.description,
  input_schema: tool.input_schema,
  name: tool.name
});
var buildRequestBody = (params) => {
  const messages = params.messages.filter((msg) => msg.role !== "system").map(mapMessage);
  const body = {
    max_tokens: MAX_TOKENS,
    messages,
    model: params.model,
    stream: true
  };
  if (params.systemPrompt) {
    body.system = params.systemPrompt;
  }
  if (params.tools && params.tools.length > 0) {
    body.tools = params.tools.map(mapToolDefinition);
  }
  if (params.thinking) {
    body.thinking = params.thinking;
    body.max_tokens = Math.max(MAX_TOKENS, params.thinking.budget_tokens + MAX_TOKENS);
  }
  return body;
};
var classifyLine = (line) => {
  if (line.startsWith("event: ")) {
    return {
      field: "event",
      value: line.slice(EVENT_PREFIX_LENGTH)
    };
  }
  if (line.startsWith("data: ")) {
    return {
      field: "data",
      value: line.slice(DATA_PREFIX_LENGTH)
    };
  }
  return;
};
var applyClassified = (acc, classified) => {
  if (!classified) {
    return acc;
  }
  if (classified.field === "event") {
    return { eventData: acc.eventData, eventType: classified.value };
  }
  return { eventData: classified.value, eventType: acc.eventType };
};
var parseEventLines = (event) => event.split(`
`).reduce((acc, line) => applyClassified(acc, classifyLine(line)), {
  eventData: "",
  eventType: ""
});
var safeParse = (text) => {
  try {
    const result = JSON.parse(text);
    return result;
  } catch {
    return;
  }
};
var tryParseJson = (text) => {
  const result = safeParse(text);
  if (isRecord(result)) {
    return result;
  }
  return;
};
var getRecord = (obj, key) => {
  const val = obj[key];
  if (isRecord(val)) {
    return val;
  }
  return;
};
var getString = (obj, key) => {
  const val = obj[key];
  if (typeof val === "string") {
    return val;
  }
  return "";
};
var getNumber = (obj, key) => {
  const val = obj[key];
  if (typeof val === "number") {
    return val;
  }
  return 0;
};
var handleContentBlockStart = (parsed, state) => {
  const block = getRecord(parsed, "content_block");
  if (block && block.type === "tool_use") {
    state.currentToolId = getString(block, "id");
    state.currentToolName = getString(block, "name");
    state.toolInputJson = "";
    state.isThinkingBlock = false;
  } else if (block && block.type === "thinking") {
    state.isThinkingBlock = true;
    state.thinkingSignature = "";
  } else {
    state.isThinkingBlock = false;
  }
};
var handleContentBlockDelta = (parsed, state) => {
  const delta = getRecord(parsed, "delta");
  if (!delta) {
    return;
  }
  if (delta.type === "thinking_delta") {
    return {
      content: getString(delta, "thinking"),
      type: "thinking"
    };
  }
  if (delta.type === "text_delta") {
    return {
      content: getString(delta, "text"),
      type: "text"
    };
  }
  if (delta.type === "input_json_delta") {
    state.toolInputJson += getString(delta, "partial_json");
  }
  if (delta.type === "signature_delta") {
    state.thinkingSignature += getString(delta, "signature");
  }
  return;
};
var handleContentBlockStop = (state) => {
  if (state.isThinkingBlock && state.thinkingSignature) {
    state.isThinkingBlock = false;
    const signature = state.thinkingSignature;
    state.thinkingSignature = "";
    return {
      content: "",
      signature,
      type: "thinking"
    };
  }
  if (!state.currentToolId) {
    return;
  }
  const input = tryParseJson(state.toolInputJson) ?? state.toolInputJson;
  const chunk = {
    id: state.currentToolId,
    input,
    name: state.currentToolName,
    type: "tool_use"
  };
  state.currentToolId = "";
  state.currentToolName = "";
  state.toolInputJson = "";
  return chunk;
};
var extractUsage = (usageRecord, existingUsage) => {
  if (!usageRecord) {
    return existingUsage;
  }
  return {
    inputTokens: getNumber(usageRecord, "input_tokens") || existingUsage?.inputTokens || 0,
    outputTokens: getNumber(usageRecord, "output_tokens") || existingUsage?.outputTokens || 0
  };
};
var handleMessageDelta = (parsed, state) => {
  const deltaUsage = getRecord(parsed, "usage");
  state.usage = extractUsage(deltaUsage, state.usage);
};
var handleMessageStart = (parsed, state) => {
  const message = getRecord(parsed, "message");
  if (!message) {
    return;
  }
  const startUsage = getRecord(message, "usage");
  state.usage = extractUsage(startUsage, state.usage);
};
var handleError = (parsed) => {
  const error = getRecord(parsed, "error");
  const errorMessage = error ? getString(error, "message") : "";
  throw new Error(errorMessage || "Anthropic API error");
};
var processEvent = (eventType, parsed, state) => {
  switch (eventType) {
    case "content_block_start": {
      handleContentBlockStart(parsed, state);
      return;
    }
    case "content_block_delta": {
      return handleContentBlockDelta(parsed, state);
    }
    case "content_block_stop": {
      return handleContentBlockStop(state);
    }
    case "message_delta": {
      handleMessageDelta(parsed, state);
      return;
    }
    case "message_start": {
      handleMessageStart(parsed, state);
      return;
    }
    case "message_stop": {
      return { type: "done", usage: state.usage };
    }
    case "error": {
      handleError(parsed);
      return;
    }
    default: {
      return;
    }
  }
};
var processSingleEvent = (event, state) => {
  if (!event.trim()) {
    return;
  }
  const { eventData, eventType } = parseEventLines(event);
  if (!eventData) {
    return;
  }
  const parsed = tryParseJson(eventData);
  if (!parsed) {
    return;
  }
  return processEvent(eventType, parsed, state);
};
var collectChunk = (event, state) => {
  const chunk = processSingleEvent(event, state);
  return chunk ? [chunk] : [];
};
var processBufferedEvents = (eventsText, state) => {
  const events = eventsText.split(`

`);
  state.buffer = events.pop() ?? "";
  return events.flatMap((event) => collectChunk(event, state));
};
var readNextChunks = async (reader, decoder, state, signal) => {
  if (signal?.aborted) {
    return { chunks: EMPTY_CHUNKS, done: true };
  }
  const { done, value } = await reader.read();
  if (done) {
    return { chunks: EMPTY_CHUNKS, done: true };
  }
  const rawText = state.buffer + decoder.decode(value, { stream: true });
  const chunks = processBufferedEvents(rawText, state);
  return { chunks, done: false };
};
var findDoneChunk = (chunks) => chunks.findIndex((c) => c.type === "done");
var sseStreamLoop = async (reader, decoder, state, signal) => {
  const result = await readNextChunks(reader, decoder, state, signal);
  if (result.done) {
    return { chunks: result.chunks, finished: true };
  }
  const doneIdx = findDoneChunk(result.chunks);
  if (doneIdx >= 0) {
    return { chunks: result.chunks.slice(0, doneIdx + 1), finished: true };
  }
  return { chunks: result.chunks, finished: false };
};
async function* streamChunks(reader, decoder, state, signal) {
  let finished = false;
  while (!finished) {
    const result = await sseStreamLoop(reader, decoder, state, signal);
    ({ finished } = result);
    yield* result.chunks;
  }
}
async function* parseSSEStream(body, signal) {
  const reader = body.getReader();
  const decoder = new TextDecoder;
  const state = {
    buffer: "",
    currentToolId: "",
    currentToolName: "",
    isThinkingBlock: false,
    thinkingSignature: "",
    toolInputJson: "",
    usage: undefined
  };
  try {
    yield* streamChunks(reader, decoder, state, signal);
  } finally {
    reader.releaseLock();
  }
}
var fetchAndStream = async function* (baseUrl, config, params) {
  const body = buildRequestBody(params);
  const response = await fetch(`${baseUrl}/v1/messages`, {
    body: JSON.stringify(body),
    headers: {
      "anthropic-version": API_VERSION,
      "Content-Type": "application/json",
      "x-api-key": config.apiKey
    },
    method: "POST",
    signal: params.signal
  });
  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Anthropic API error ${response.status}: ${errorText}`);
  }
  if (!response.body) {
    throw new Error("Anthropic API returned no response body");
  }
  yield* parseSSEStream(response.body, params.signal);
};
var anthropic = (config) => {
  const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
  return {
    stream: (params) => fetchAndStream(baseUrl, config, params)
  };
};
export {
  anthropic
};

//# debugId=240C8AA4B0AB130464756E2164756E21
//# sourceMappingURL=anthropic.js.map
