import {
  LangChainAdapter
} from "./chunk-DCEEHMLJ.mjs";
import {
  convertServiceAdapterError
} from "./chunk-AMUJQ6IR.mjs";
import {
  __name
} from "./chunk-FHD4JECV.mjs";

// src/service-adapters/langchain/langserve.ts
import { RemoteRunnable } from "langchain/runnables/remote";
var RemoteChain = class {
  name;
  description;
  chainUrl;
  parameters;
  parameterType;
  constructor(options) {
    this.name = options.name;
    this.description = options.description;
    this.chainUrl = options.chainUrl;
    this.parameters = options.parameters;
    this.parameterType = options.parameterType || "multi";
  }
  async toAction() {
    if (!this.parameters) {
      await this.inferLangServeParameters();
    }
    return {
      name: this.name,
      description: this.description,
      parameters: this.parameters,
      handler: async (args) => {
        const runnable = new RemoteRunnable({
          url: this.chainUrl
        });
        let input;
        if (this.parameterType === "single") {
          input = args[Object.keys(args)[0]];
        } else {
          input = args;
        }
        return await runnable.invoke(input);
      }
    };
  }
  async inferLangServeParameters() {
    const supportedTypes = [
      "string",
      "number",
      "boolean"
    ];
    let schemaUrl = this.chainUrl.replace(/\/+$/, "") + "/input_schema";
    let schema = await fetch(schemaUrl).then((res) => res.json()).catch(() => {
      throw new Error("Failed to fetch langserve schema at " + schemaUrl);
    });
    if (supportedTypes.includes(schema.type)) {
      this.parameterType = "single";
      this.parameters = [
        {
          name: "input",
          type: schema.type,
          description: "The input to the chain"
        }
      ];
    } else if (schema.type === "object") {
      this.parameterType = "multi";
      this.parameters = Object.keys(schema.properties).map((key) => {
        var _a;
        let property = schema.properties[key];
        if (!supportedTypes.includes(property.type)) {
          throw new Error("Unsupported schema type");
        }
        return {
          name: key,
          type: property.type,
          description: property.description || "",
          required: ((_a = schema.required) == null ? void 0 : _a.includes(key)) || false
        };
      });
    } else {
      throw new Error("Unsupported schema type");
    }
  }
};
__name(RemoteChain, "RemoteChain");

// src/service-adapters/anthropic/anthropic-adapter.ts
import Anthropic from "@anthropic-ai/sdk";

// src/service-adapters/anthropic/utils.ts
function limitMessagesToTokenCount(messages, tools, model, maxTokens) {
  maxTokens || (maxTokens = MAX_TOKENS);
  const result = [];
  const toolsNumTokens = countToolsTokens(model, tools);
  if (toolsNumTokens > maxTokens) {
    throw new Error(`Too many tokens in function definitions: ${toolsNumTokens} > ${maxTokens}`);
  }
  maxTokens -= toolsNumTokens;
  for (const message of messages) {
    if (message.role === "system") {
      const numTokens = countMessageTokens(model, message);
      maxTokens -= numTokens;
      if (maxTokens < 0) {
        throw new Error("Not enough tokens for system message.");
      }
    }
  }
  let cutoff = false;
  const reversedMessages = [
    ...messages
  ].reverse();
  for (const message of reversedMessages) {
    if (message.role === "system") {
      result.unshift(message);
      continue;
    } else if (cutoff) {
      continue;
    }
    let numTokens = countMessageTokens(model, message);
    if (maxTokens < numTokens) {
      cutoff = true;
      continue;
    }
    result.unshift(message);
    maxTokens -= numTokens;
  }
  return result;
}
__name(limitMessagesToTokenCount, "limitMessagesToTokenCount");
var MAX_TOKENS = 128e3;
function countToolsTokens(model, tools) {
  if (tools.length === 0) {
    return 0;
  }
  const json = JSON.stringify(tools);
  return countTokens(model, json);
}
__name(countToolsTokens, "countToolsTokens");
function countMessageTokens(model, message) {
  return countTokens(model, JSON.stringify(message.content) || "");
}
__name(countMessageTokens, "countMessageTokens");
function countTokens(model, text) {
  return text.length / 3;
}
__name(countTokens, "countTokens");
function convertActionInputToAnthropicTool(action) {
  return {
    name: action.name,
    description: action.description,
    input_schema: JSON.parse(action.jsonSchema)
  };
}
__name(convertActionInputToAnthropicTool, "convertActionInputToAnthropicTool");
function convertMessageToAnthropicMessage(message) {
  if (message.isTextMessage()) {
    if (message.role === "system") {
      return {
        role: "assistant",
        content: [
          {
            type: "text",
            text: "THE FOLLOWING MESSAGE IS A SYSTEM MESSAGE: " + message.content
          }
        ]
      };
    } else {
      return {
        role: message.role === "user" ? "user" : "assistant",
        content: [
          {
            type: "text",
            text: message.content
          }
        ]
      };
    }
  } else if (message.isImageMessage()) {
    let mediaType;
    switch (message.format) {
      case "jpeg":
        mediaType = "image/jpeg";
        break;
      case "png":
        mediaType = "image/png";
        break;
      case "webp":
        mediaType = "image/webp";
        break;
      case "gif":
        mediaType = "image/gif";
        break;
      default:
        throw new Error(`Unsupported image format: ${message.format}`);
    }
    return {
      role: "user",
      content: [
        {
          type: "image",
          source: {
            type: "base64",
            media_type: mediaType,
            data: message.bytes
          }
        }
      ]
    };
  } else if (message.isActionExecutionMessage()) {
    return {
      role: "assistant",
      content: [
        {
          id: message.id,
          type: "tool_use",
          input: message.arguments,
          name: message.name
        }
      ]
    };
  } else if (message.isResultMessage()) {
    return {
      role: "user",
      content: [
        {
          type: "tool_result",
          content: message.result || "Action completed successfully",
          tool_use_id: message.actionExecutionId
        }
      ]
    };
  }
}
__name(convertMessageToAnthropicMessage, "convertMessageToAnthropicMessage");

// src/service-adapters/anthropic/anthropic-adapter.ts
import { randomId, randomUUID } from "@copilotkit/shared";
var DEFAULT_MODEL = "claude-3-5-sonnet-latest";
var AnthropicAdapter = class {
  model = DEFAULT_MODEL;
  provider = "anthropic";
  promptCaching;
  _anthropic;
  get anthropic() {
    return this._anthropic;
  }
  get name() {
    return "AnthropicAdapter";
  }
  constructor(params) {
    this._anthropic = (params == null ? void 0 : params.anthropic) || new Anthropic({});
    if (params == null ? void 0 : params.model) {
      this.model = params.model;
    }
    this.promptCaching = (params == null ? void 0 : params.promptCaching) || {
      enabled: false
    };
  }
  /**
  * Adds cache control to system prompt
  */
  addSystemPromptCaching(system, debug = false) {
    if (!this.promptCaching.enabled || !system) {
      return system;
    }
    const originalTextLength = system.length;
    if (debug) {
      console.log(`[ANTHROPIC CACHE DEBUG] Added cache control to system prompt (${originalTextLength} chars).`);
    }
    return [
      {
        type: "text",
        text: system,
        cache_control: {
          type: "ephemeral"
        }
      }
    ];
  }
  /**
  * Adds cache control to the final message
  */
  addIncrementalMessageCaching(messages, debug = false) {
    if (!this.promptCaching.enabled || messages.length === 0) {
      return messages;
    }
    const finalMessage = messages[messages.length - 1];
    const messageNumber = messages.length;
    if (Array.isArray(finalMessage.content) && finalMessage.content.length > 0) {
      const finalBlock = finalMessage.content[finalMessage.content.length - 1];
      const updatedMessages = [
        ...messages.slice(0, -1),
        {
          ...finalMessage,
          content: [
            ...finalMessage.content.slice(0, -1),
            {
              ...finalBlock,
              cache_control: {
                type: "ephemeral"
              }
            }
          ]
        }
      ];
      if (debug) {
        console.log(`[ANTHROPIC CACHE DEBUG] Added cache control to final message (message ${messageNumber}).`);
      }
      return updatedMessages;
    }
    return messages;
  }
  shouldGenerateFallbackResponse(messages) {
    var _a, _b, _c;
    if (messages.length === 0)
      return false;
    const lastMessage = messages[messages.length - 1];
    const endsWithToolResult = lastMessage.role === "user" && Array.isArray(lastMessage.content) && lastMessage.content.some((content) => content.type === "tool_result");
    if (messages.length >= 3 && endsWithToolResult) {
      const lastThree = messages.slice(-3);
      const hasRecentToolPattern = ((_a = lastThree[0]) == null ? void 0 : _a.role) === "user" && // Initial user message
      ((_b = lastThree[1]) == null ? void 0 : _b.role) === "assistant" && // Assistant tool use
      Array.isArray(lastThree[1].content) && lastThree[1].content.some((content) => content.type === "tool_use") && ((_c = lastThree[2]) == null ? void 0 : _c.role) === "user" && // Tool result
      Array.isArray(lastThree[2].content) && lastThree[2].content.some((content) => content.type === "tool_result");
      return hasRecentToolPattern;
    }
    return endsWithToolResult;
  }
  async process(request) {
    const { threadId, model = this.model, messages: rawMessages, actions, eventSource, forwardedParameters } = request;
    const tools = actions.map(convertActionInputToAnthropicTool);
    const messages = [
      ...rawMessages
    ];
    const instructionsMessage = messages.shift();
    const instructions = instructionsMessage.isTextMessage() ? instructionsMessage.content : "";
    const validToolUseIds = /* @__PURE__ */ new Set();
    for (const message of messages) {
      if (message.isActionExecutionMessage()) {
        validToolUseIds.add(message.id);
      }
    }
    const processedToolResultIds = /* @__PURE__ */ new Set();
    const anthropicMessages = messages.map((message) => {
      if (message.isResultMessage()) {
        if (!validToolUseIds.has(message.actionExecutionId)) {
          return null;
        }
        if (processedToolResultIds.has(message.actionExecutionId)) {
          return null;
        }
        processedToolResultIds.add(message.actionExecutionId);
        return {
          role: "user",
          content: [
            {
              type: "tool_result",
              content: message.result || "Action completed successfully",
              tool_use_id: message.actionExecutionId
            }
          ]
        };
      }
      return convertMessageToAnthropicMessage(message);
    }).filter(Boolean).filter((msg) => {
      if (msg.role === "assistant" && Array.isArray(msg.content)) {
        const hasEmptyTextOnly = msg.content.length === 1 && msg.content[0].type === "text" && (!msg.content[0].text || msg.content[0].text.trim() === "");
        return !hasEmptyTextOnly;
      }
      return true;
    });
    const limitedMessages = limitMessagesToTokenCount(anthropicMessages, tools, model);
    const cachedSystemPrompt = this.addSystemPromptCaching(instructions, this.promptCaching.debug);
    const cachedMessages = this.addIncrementalMessageCaching(limitedMessages, this.promptCaching.debug);
    let toolChoice = forwardedParameters == null ? void 0 : forwardedParameters.toolChoice;
    if ((forwardedParameters == null ? void 0 : forwardedParameters.toolChoice) === "function") {
      toolChoice = {
        type: "tool",
        name: forwardedParameters.toolChoiceFunctionName
      };
    }
    try {
      const createParams = {
        system: cachedSystemPrompt,
        model: this.model,
        messages: cachedMessages,
        max_tokens: (forwardedParameters == null ? void 0 : forwardedParameters.maxTokens) || 1024,
        ...(forwardedParameters == null ? void 0 : forwardedParameters.temperature) ? {
          temperature: forwardedParameters.temperature
        } : {},
        ...tools.length > 0 && {
          tools
        },
        ...toolChoice && {
          tool_choice: toolChoice
        },
        stream: true
      };
      const stream = await this.anthropic.messages.create(createParams);
      eventSource.stream(async (eventStream$) => {
        let mode = null;
        let didOutputText = false;
        let currentMessageId = randomId();
        let currentToolCallId = randomId();
        let filterThinkingTextBuffer = new FilterThinkingTextBuffer();
        let hasReceivedContent = false;
        try {
          for await (const chunk of stream) {
            if (chunk.type === "message_start") {
              currentMessageId = chunk.message.id;
            } else if (chunk.type === "content_block_start") {
              hasReceivedContent = true;
              if (chunk.content_block.type === "text") {
                didOutputText = false;
                filterThinkingTextBuffer.reset();
                mode = "message";
              } else if (chunk.content_block.type === "tool_use") {
                currentToolCallId = chunk.content_block.id;
                eventStream$.sendActionExecutionStart({
                  actionExecutionId: currentToolCallId,
                  actionName: chunk.content_block.name,
                  parentMessageId: currentMessageId
                });
                mode = "function";
              }
            } else if (chunk.type === "content_block_delta") {
              if (chunk.delta.type === "text_delta") {
                const text = filterThinkingTextBuffer.onTextChunk(chunk.delta.text);
                if (text.length > 0) {
                  if (!didOutputText) {
                    eventStream$.sendTextMessageStart({
                      messageId: currentMessageId
                    });
                    didOutputText = true;
                  }
                  eventStream$.sendTextMessageContent({
                    messageId: currentMessageId,
                    content: text
                  });
                }
              } else if (chunk.delta.type === "input_json_delta") {
                eventStream$.sendActionExecutionArgs({
                  actionExecutionId: currentToolCallId,
                  args: chunk.delta.partial_json
                });
              }
            } else if (chunk.type === "content_block_stop") {
              if (mode === "message") {
                if (didOutputText) {
                  eventStream$.sendTextMessageEnd({
                    messageId: currentMessageId
                  });
                }
              } else if (mode === "function") {
                eventStream$.sendActionExecutionEnd({
                  actionExecutionId: currentToolCallId
                });
              }
            }
          }
        } catch (error) {
          throw convertServiceAdapterError(error, "Anthropic");
        }
        if (!hasReceivedContent && this.shouldGenerateFallbackResponse(cachedMessages)) {
          let fallbackContent = "Task completed successfully.";
          const lastMessage = cachedMessages[cachedMessages.length - 1];
          if ((lastMessage == null ? void 0 : lastMessage.role) === "user" && Array.isArray(lastMessage.content)) {
            const toolResult = lastMessage.content.find((c) => c.type === "tool_result");
            if ((toolResult == null ? void 0 : toolResult.content) && toolResult.content !== "Action completed successfully") {
              fallbackContent = toolResult.content;
            }
          }
          currentMessageId = randomId();
          eventStream$.sendTextMessageStart({
            messageId: currentMessageId
          });
          eventStream$.sendTextMessageContent({
            messageId: currentMessageId,
            content: fallbackContent
          });
          eventStream$.sendTextMessageEnd({
            messageId: currentMessageId
          });
        }
        eventStream$.complete();
      });
    } catch (error) {
      throw convertServiceAdapterError(error, "Anthropic");
    }
    return {
      threadId: threadId || randomUUID()
    };
  }
};
__name(AnthropicAdapter, "AnthropicAdapter");
var THINKING_TAG = "<thinking>";
var THINKING_TAG_END = "</thinking>";
var FilterThinkingTextBuffer = /* @__PURE__ */ __name(class FilterThinkingTextBuffer2 {
  buffer;
  didFilterThinkingTag = false;
  constructor() {
    this.buffer = "";
  }
  onTextChunk(text) {
    this.buffer += text;
    if (this.didFilterThinkingTag) {
      return text;
    }
    const potentialTag = this.buffer.slice(0, THINKING_TAG.length);
    if (THINKING_TAG.startsWith(potentialTag)) {
      if (this.buffer.includes(THINKING_TAG_END)) {
        const end = this.buffer.indexOf(THINKING_TAG_END);
        const filteredText = this.buffer.slice(end + THINKING_TAG_END.length);
        this.buffer = filteredText;
        this.didFilterThinkingTag = true;
        return filteredText;
      } else {
        return "";
      }
    }
    return text;
  }
  reset() {
    this.buffer = "";
    this.didFilterThinkingTag = false;
  }
}, "FilterThinkingTextBuffer");

// src/service-adapters/experimental/ollama/ollama-adapter.ts
import { Ollama } from "@langchain/community/llms/ollama";
import { randomId as randomId2, randomUUID as randomUUID2 } from "@copilotkit/shared";
var DEFAULT_MODEL2 = "llama3:latest";
var ExperimentalOllamaAdapter = class {
  model;
  provider = "ollama";
  get name() {
    return "OllamaAdapter";
  }
  constructor(options) {
    if (options == null ? void 0 : options.model) {
      this.model = options.model;
    } else {
      this.model = DEFAULT_MODEL2;
    }
  }
  async process(request) {
    const { messages, actions, eventSource } = request;
    const ollama = new Ollama({
      model: this.model
    });
    const contents = messages.filter((m) => m.isTextMessage()).map((m) => m.content);
    const _stream = await ollama.stream(contents);
    eventSource.stream(async (eventStream$) => {
      const currentMessageId = randomId2();
      eventStream$.sendTextMessageStart({
        messageId: currentMessageId
      });
      for await (const chunkText of _stream) {
        eventStream$.sendTextMessageContent({
          messageId: currentMessageId,
          content: chunkText
        });
      }
      eventStream$.sendTextMessageEnd({
        messageId: currentMessageId
      });
      eventStream$.complete();
    });
    return {
      threadId: request.threadId || randomUUID2()
    };
  }
};
__name(ExperimentalOllamaAdapter, "ExperimentalOllamaAdapter");

// src/service-adapters/bedrock/bedrock-adapter.ts
import { ChatBedrockConverse } from "@langchain/aws";
var DEFAULT_MODEL3 = "amazon.nova-lite-v1:0";
var BedrockAdapter = class extends LangChainAdapter {
  provider = "bedrock";
  model = DEFAULT_MODEL3;
  constructor(options) {
    super({
      chainFn: async ({ messages, tools, threadId }) => {
        this.model = (options == null ? void 0 : options.model) ?? "amazon.nova-lite-v1:0";
        const model = new ChatBedrockConverse({
          model: this.model,
          region: (options == null ? void 0 : options.region) ?? "us-east-1",
          credentials: (options == null ? void 0 : options.credentials) ? {
            accessKeyId: options.credentials.accessKeyId,
            secretAccessKey: options.credentials.secretAccessKey
          } : void 0
        }).bindTools(tools);
        return model.stream(messages);
      }
    });
  }
};
__name(BedrockAdapter, "BedrockAdapter");

// src/service-adapters/empty/empty-adapter.ts
import { randomUUID as randomUUID3 } from "@copilotkit/shared";
var EmptyAdapter = class {
  async process(request) {
    return {
      threadId: request.threadId || randomUUID3()
    };
  }
  get name() {
    return "EmptyAdapter";
  }
};
__name(EmptyAdapter, "EmptyAdapter");
var ExperimentalEmptyAdapter = EmptyAdapter;

export {
  RemoteChain,
  AnthropicAdapter,
  ExperimentalOllamaAdapter,
  BedrockAdapter,
  EmptyAdapter,
  ExperimentalEmptyAdapter
};
//# sourceMappingURL=chunk-ERUOA47O.mjs.map