'use strict';

var chunkC73WLCY3_cjs = require('./chunk-C73WLCY3.cjs');
var crypto = require('crypto');
var AIV4 = require('ai');
var AIV5 = require('ai-v5');
var providerUtils = require('@ai-sdk/provider-utils');
var zod = require('zod');

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n.default = e;
  return Object.freeze(n);
}

var AIV4__namespace = /*#__PURE__*/_interopNamespace(AIV4);
var AIV5__namespace = /*#__PURE__*/_interopNamespace(AIV5);

var DefaultGeneratedFile = class {
  base64Data;
  uint8ArrayData;
  mediaType;
  constructor({ data, mediaType }) {
    const isUint8Array = data instanceof Uint8Array;
    this.base64Data = isUint8Array ? void 0 : data;
    this.uint8ArrayData = isUint8Array ? data : void 0;
    this.mediaType = mediaType;
  }
  // lazy conversion with caching to avoid unnecessary conversion overhead:
  get base64() {
    if (this.base64Data == null) {
      this.base64Data = providerUtils.convertUint8ArrayToBase64(this.uint8ArrayData);
    }
    return this.base64Data;
  }
  // lazy conversion with caching to avoid unnecessary conversion overhead:
  get uint8Array() {
    if (this.uint8ArrayData == null) {
      this.uint8ArrayData = providerUtils.convertBase64ToUint8Array(this.base64Data);
    }
    return this.uint8ArrayData;
  }
};
var DefaultGeneratedFileWithType = class extends DefaultGeneratedFile {
  type = "file";
  constructor(options) {
    super(options);
  }
};

// src/agent/message-list/prompt/attachments-to-parts.ts
function attachmentsToParts(attachments) {
  const parts = [];
  for (const attachment of attachments) {
    let url;
    try {
      url = new URL(attachment.url);
    } catch {
      throw new Error(`Invalid URL: ${attachment.url}`);
    }
    switch (url.protocol) {
      case "http:":
      case "https:": {
        if (attachment.contentType?.startsWith("image/")) {
          parts.push({ type: "image", image: url.toString(), mimeType: attachment.contentType });
        } else {
          if (!attachment.contentType) {
            throw new Error("If the attachment is not an image, it must specify a content type");
          }
          parts.push({
            type: "file",
            data: url.toString(),
            mimeType: attachment.contentType
          });
        }
        break;
      }
      case "data:": {
        if (attachment.contentType?.startsWith("image/")) {
          parts.push({
            type: "image",
            image: attachment.url,
            mimeType: attachment.contentType
          });
        } else if (attachment.contentType?.startsWith("text/")) {
          parts.push({
            type: "file",
            data: attachment.url,
            mimeType: attachment.contentType
          });
        } else {
          if (!attachment.contentType) {
            throw new Error("If the attachment is not an image or text, it must specify a content type");
          }
          parts.push({
            type: "file",
            data: attachment.url,
            mimeType: attachment.contentType
          });
        }
        break;
      }
      default: {
        throw new Error(`Unsupported URL protocol: ${url.protocol}`);
      }
    }
  }
  return parts;
}

// src/agent/message-list/prompt/convert-to-mastra-v1.ts
var makePushOrCombine = (v1Messages) => {
  const idUsageCount = /* @__PURE__ */ new Map();
  const SPLIT_SUFFIX_PATTERN = /__split-\d+$/;
  return (msg) => {
    const previousMessage = v1Messages.at(-1);
    if (msg.role === previousMessage?.role && Array.isArray(previousMessage.content) && Array.isArray(msg.content) && // we were creating new messages for tool calls before and not appending to the assistant message
    // so don't append here so everything works as before
    (msg.role !== `assistant` || msg.role === `assistant` && msg.content.at(-1)?.type !== `tool-call`)) {
      for (const part of msg.content) {
        previousMessage.content.push(part);
      }
    } else {
      let baseId = msg.id;
      const hasSplitSuffix = SPLIT_SUFFIX_PATTERN.test(baseId);
      if (hasSplitSuffix) {
        v1Messages.push(msg);
        return;
      }
      const currentCount = idUsageCount.get(baseId) || 0;
      if (currentCount > 0) {
        msg.id = `${baseId}__split-${currentCount}`;
      }
      idUsageCount.set(baseId, currentCount + 1);
      v1Messages.push(msg);
    }
  };
};
function convertToV1Messages(messages) {
  const v1Messages = [];
  const pushOrCombine = makePushOrCombine(v1Messages);
  for (let i = 0; i < messages.length; i++) {
    const message = messages[i];
    const isLastMessage = i === messages.length - 1;
    if (!message?.content) continue;
    const { content, experimental_attachments: inputAttachments = [], parts: inputParts } = message.content;
    const { role } = message;
    const fields = {
      id: message.id,
      createdAt: message.createdAt,
      resourceId: message.resourceId,
      threadId: message.threadId
    };
    const experimental_attachments = [...inputAttachments];
    const parts = [];
    for (const part of inputParts) {
      if (part.type === "file") {
        experimental_attachments.push({
          url: part.data,
          contentType: part.mimeType
        });
      } else {
        parts.push(part);
      }
    }
    switch (role) {
      case "user": {
        if (parts == null) {
          const userContent = experimental_attachments ? [{ type: "text", text: content || "" }, ...attachmentsToParts(experimental_attachments)] : { type: "text", text: content || "" };
          pushOrCombine({
            role: "user",
            ...fields,
            type: "text",
            // @ts-ignore
            content: userContent
          });
        } else {
          const textParts = message.content.parts.filter((part) => part.type === "text").map((part) => ({
            type: "text",
            text: part.text
          }));
          const userContent = experimental_attachments ? [...textParts, ...attachmentsToParts(experimental_attachments)] : textParts;
          pushOrCombine({
            role: "user",
            ...fields,
            type: "text",
            content: Array.isArray(userContent) && userContent.length === 1 && userContent[0]?.type === `text` && typeof content !== `undefined` ? content : userContent
          });
        }
        break;
      }
      case "assistant": {
        if (message.content.parts != null) {
          let processBlock2 = function() {
            const content2 = [];
            for (const part of block) {
              switch (part.type) {
                case "file":
                case "text": {
                  content2.push(part);
                  break;
                }
                case "reasoning": {
                  for (const detail of part.details) {
                    switch (detail.type) {
                      case "text":
                        content2.push({
                          type: "reasoning",
                          text: detail.text,
                          signature: detail.signature
                        });
                        break;
                      case "redacted":
                        content2.push({
                          type: "redacted-reasoning",
                          data: detail.data
                        });
                        break;
                    }
                  }
                  break;
                }
                case "tool-invocation":
                  if (part.toolInvocation.toolName !== "updateWorkingMemory") {
                    content2.push({
                      type: "tool-call",
                      toolCallId: part.toolInvocation.toolCallId,
                      toolName: part.toolInvocation.toolName,
                      args: part.toolInvocation.args
                    });
                  }
                  break;
              }
            }
            pushOrCombine({
              role: "assistant",
              ...fields,
              type: content2.some((c) => c.type === `tool-call`) ? "tool-call" : "text",
              // content: content,
              content: typeof content2 !== `string` && Array.isArray(content2) && content2.length === 1 && content2[0]?.type === `text` ? message?.content?.content || content2 : content2
            });
            const stepInvocations = block.filter((part) => `type` in part && part.type === "tool-invocation").map((part) => part.toolInvocation).filter((ti) => ti.toolName !== "updateWorkingMemory");
            const invocationsWithResults = stepInvocations.filter((ti) => ti.state === "result" && "result" in ti);
            if (invocationsWithResults.length > 0) {
              pushOrCombine({
                role: "tool",
                ...fields,
                type: "tool-result",
                content: invocationsWithResults.map((toolInvocation) => {
                  const { toolCallId, toolName, result } = toolInvocation;
                  return {
                    type: "tool-result",
                    toolCallId,
                    toolName,
                    result
                  };
                })
              });
            }
            block = [];
            blockHasToolInvocations = false;
            currentStep++;
          };
          let currentStep = 0;
          let blockHasToolInvocations = false;
          let block = [];
          for (const part of message.content.parts) {
            switch (part.type) {
              case "text": {
                if (blockHasToolInvocations) {
                  processBlock2();
                }
                block.push(part);
                break;
              }
              case "file":
              case "reasoning": {
                block.push(part);
                break;
              }
              case "tool-invocation": {
                const hasNonToolContent = block.some(
                  (p) => p.type === "text" || p.type === "file" || p.type === "reasoning"
                );
                if (hasNonToolContent || (part.toolInvocation.step ?? 0) !== currentStep) {
                  processBlock2();
                }
                block.push(part);
                blockHasToolInvocations = true;
                break;
              }
            }
          }
          processBlock2();
          const toolInvocations2 = message.content.toolInvocations;
          if (toolInvocations2 && toolInvocations2.length > 0) {
            const processedToolCallIds = /* @__PURE__ */ new Set();
            for (const part of message.content.parts) {
              if (part.type === "tool-invocation" && part.toolInvocation.toolCallId) {
                processedToolCallIds.add(part.toolInvocation.toolCallId);
              }
            }
            const unprocessedToolInvocations = toolInvocations2.filter(
              (ti) => !processedToolCallIds.has(ti.toolCallId) && ti.toolName !== "updateWorkingMemory"
            );
            if (unprocessedToolInvocations.length > 0) {
              const invocationsByStep = /* @__PURE__ */ new Map();
              for (const inv of unprocessedToolInvocations) {
                const step = inv.step ?? 0;
                if (!invocationsByStep.has(step)) {
                  invocationsByStep.set(step, []);
                }
                invocationsByStep.get(step).push(inv);
              }
              const sortedSteps = Array.from(invocationsByStep.keys()).sort((a, b) => a - b);
              for (const step of sortedSteps) {
                const stepInvocations = invocationsByStep.get(step);
                pushOrCombine({
                  role: "assistant",
                  ...fields,
                  type: "tool-call",
                  content: [
                    ...stepInvocations.map(({ toolCallId, toolName, args }) => ({
                      type: "tool-call",
                      toolCallId,
                      toolName,
                      args
                    }))
                  ]
                });
                const invocationsWithResults = stepInvocations.filter((ti) => ti.state === "result" && "result" in ti);
                if (invocationsWithResults.length > 0) {
                  pushOrCombine({
                    role: "tool",
                    ...fields,
                    type: "tool-result",
                    content: invocationsWithResults.map((toolInvocation) => {
                      const { toolCallId, toolName, result } = toolInvocation;
                      return {
                        type: "tool-result",
                        toolCallId,
                        toolName,
                        result
                      };
                    })
                  });
                }
              }
            }
          }
          break;
        }
        const toolInvocations = message.content.toolInvocations;
        if (toolInvocations == null || toolInvocations.length === 0) {
          pushOrCombine({ role: "assistant", ...fields, content: content || "", type: "text" });
          break;
        }
        const maxStep = toolInvocations.reduce((max, toolInvocation) => {
          return Math.max(max, toolInvocation.step ?? 0);
        }, 0);
        for (let i2 = 0; i2 <= maxStep; i2++) {
          const stepInvocations = toolInvocations.filter(
            (toolInvocation) => (toolInvocation.step ?? 0) === i2 && toolInvocation.toolName !== "updateWorkingMemory"
          );
          if (stepInvocations.length === 0) {
            continue;
          }
          pushOrCombine({
            role: "assistant",
            ...fields,
            type: "tool-call",
            content: [
              ...isLastMessage && content && i2 === 0 ? [{ type: "text", text: content }] : [],
              ...stepInvocations.map(({ toolCallId, toolName, args }) => ({
                type: "tool-call",
                toolCallId,
                toolName,
                args
              }))
            ]
          });
          const invocationsWithResults = stepInvocations.filter((ti) => ti.state === "result" && "result" in ti);
          if (invocationsWithResults.length > 0) {
            pushOrCombine({
              role: "tool",
              ...fields,
              type: "tool-result",
              content: invocationsWithResults.map((toolInvocation) => {
                const { toolCallId, toolName, result } = toolInvocation;
                return {
                  type: "tool-result",
                  toolCallId,
                  toolName,
                  result
                };
              })
            });
          }
        }
        if (content && !isLastMessage) {
          pushOrCombine({ role: "assistant", ...fields, type: "text", content: content || "" });
        }
        break;
      }
    }
  }
  return v1Messages;
}
zod.z.union([
  zod.z.string(),
  zod.z.instanceof(Uint8Array),
  zod.z.instanceof(ArrayBuffer),
  zod.z.custom(
    // Buffer might not be available in some environments such as CloudFlare:
    (value) => globalThis.Buffer?.isBuffer(value) ?? false,
    { message: "Must be a Buffer" }
  )
]);
function convertDataContentToBase64String(content) {
  if (typeof content === "string") {
    return content;
  }
  if (content instanceof ArrayBuffer) {
    return providerUtils.convertUint8ArrayToBase64(new Uint8Array(content));
  }
  return providerUtils.convertUint8ArrayToBase64(content);
}

// src/agent/message-list/utils/ai-v5/tool.ts
function getToolName(type) {
  if (typeof type === "object" && type && "type" in type) {
    type = type.type;
  }
  if (typeof type !== "string") {
    return "unknown";
  }
  if (type === "dynamic-tool") {
    return "dynamic-tool";
  }
  if (type.startsWith("tool-")) {
    return type.slice("tool-".length);
  }
  return type;
}

// src/agent/message-list/index.ts
var MessageList = class _MessageList {
  messages = [];
  // passed in by dev in input or context
  systemMessages = [];
  // passed in by us for a specific purpose, eg memory system message
  taggedSystemMessages = {};
  memoryInfo = null;
  // used to filter this.messages by how it was added: input/response/memory
  memoryMessages = /* @__PURE__ */ new Set();
  newUserMessages = /* @__PURE__ */ new Set();
  newResponseMessages = /* @__PURE__ */ new Set();
  userContextMessages = /* @__PURE__ */ new Set();
  memoryMessagesPersisted = /* @__PURE__ */ new Set();
  newUserMessagesPersisted = /* @__PURE__ */ new Set();
  newResponseMessagesPersisted = /* @__PURE__ */ new Set();
  userContextMessagesPersisted = /* @__PURE__ */ new Set();
  generateMessageId;
  _agentNetworkAppend = false;
  constructor({
    threadId,
    resourceId,
    generateMessageId,
    // @ts-ignore Flag for agent network messages
    _agentNetworkAppend
  } = {}) {
    if (threadId) {
      this.memoryInfo = { threadId, resourceId };
    }
    this.generateMessageId = generateMessageId;
    this._agentNetworkAppend = _agentNetworkAppend || false;
  }
  add(messages, messageSource) {
    if (messageSource === `user`) messageSource = `input`;
    if (!messages) return this;
    for (const message of Array.isArray(messages) ? messages : [messages]) {
      this.addOne(
        typeof message === `string` ? {
          role: "user",
          content: message
        } : message,
        messageSource
      );
    }
    return this;
  }
  getLatestUserContent() {
    const currentUserMessages = this.all.core().filter((m) => m.role === "user");
    const content = currentUserMessages.at(-1)?.content;
    if (!content) return null;
    return _MessageList.coreContentToString(content);
  }
  get get() {
    return {
      all: this.all,
      remembered: this.remembered,
      input: this.input,
      response: this.response
    };
  }
  get getPersisted() {
    return {
      remembered: this.rememberedPersisted,
      input: this.inputPersisted,
      taggedSystemMessages: this.taggedSystemMessages,
      response: this.responsePersisted
    };
  }
  get clear() {
    return {
      input: {
        v2: () => {
          const userMessages = Array.from(this.newUserMessages);
          this.messages = this.messages.filter((m) => !this.newUserMessages.has(m));
          this.newUserMessages.clear();
          return userMessages;
        }
      },
      response: {
        v2: () => {
          const responseMessages = Array.from(this.newResponseMessages);
          this.messages = this.messages.filter((m) => !this.newResponseMessages.has(m));
          this.newResponseMessages.clear();
          return responseMessages;
        }
      }
    };
  }
  all = {
    v3: () => this.cleanV3Metadata(this.messages.map(this.mastraMessageV2ToMastraMessageV3)),
    v2: () => this.messages,
    v1: () => convertToV1Messages(this.all.v2()),
    aiV5: {
      model: () => this.aiV5UIMessagesToAIV5ModelMessages(this.all.aiV5.ui()),
      ui: () => this.all.v3().map(_MessageList.mastraMessageV3ToAIV5UIMessage),
      // Used when calling AI SDK streamText/generateText
      prompt: () => {
        const messages = [
          ...this.aiV4CoreMessagesToAIV5ModelMessages(
            [...this.systemMessages, ...Object.values(this.taggedSystemMessages).flat()],
            `system`
          ),
          ...this.all.aiV5.model()
        ];
        const needsDefaultUserMessage = !messages.length || messages[0]?.role === "assistant";
        if (needsDefaultUserMessage) {
          const defaultMessage = {
            role: "user",
            content: " "
          };
          messages.unshift(defaultMessage);
        }
        return messages;
      },
      // Used for creating LLM prompt messages without AI SDK streamText/generateText
      llmPrompt: () => {
        const modelMessages = this.all.aiV5.model();
        const systemMessages = this.aiV4CoreMessagesToAIV5ModelMessages(
          [...this.systemMessages, ...Object.values(this.taggedSystemMessages).flat()],
          `system`
        );
        const messages = [...systemMessages, ...modelMessages];
        const needsDefaultUserMessage = !messages.length || messages[0]?.role === "assistant";
        if (needsDefaultUserMessage) {
          const defaultMessage = {
            role: "user",
            content: " "
          };
          messages.unshift(defaultMessage);
        }
        return messages.map(_MessageList.aiV5ModelMessageToV2PromptMessage);
      }
    },
    /* @deprecated use list.get.all.aiV4.prompt() instead */
    prompt: () => this.all.aiV4.prompt(),
    /* @deprecated use list.get.all.aiV4.ui() */
    ui: () => this.all.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
    /* @deprecated use list.get.all.aiV4.core() */
    core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.all.aiV4.ui()),
    aiV4: {
      ui: () => this.all.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
      core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.all.aiV4.ui()),
      // Used when calling AI SDK streamText/generateText
      prompt: () => {
        const coreMessages = this.all.aiV4.core();
        const messages = [...this.systemMessages, ...Object.values(this.taggedSystemMessages).flat(), ...coreMessages];
        const needsDefaultUserMessage = !messages.length || messages[0]?.role === "assistant";
        if (needsDefaultUserMessage) {
          const defaultMessage = {
            role: "user",
            content: " "
          };
          messages.unshift(defaultMessage);
        }
        return messages;
      },
      // Used for creating LLM prompt messages without AI SDK streamText/generateText
      llmPrompt: () => {
        const coreMessages = this.all.aiV4.core();
        const systemMessages = [...this.systemMessages, ...Object.values(this.taggedSystemMessages).flat()];
        const messages = [...systemMessages, ...coreMessages];
        const needsDefaultUserMessage = !messages.length || messages[0]?.role === "assistant";
        if (needsDefaultUserMessage) {
          const defaultMessage = {
            role: "user",
            content: " "
          };
          messages.unshift(defaultMessage);
        }
        return messages.map(_MessageList.aiV4CoreMessageToV1PromptMessage);
      }
    }
  };
  remembered = {
    v3: () => this.remembered.v2().map(this.mastraMessageV2ToMastraMessageV3),
    v2: () => this.messages.filter((m) => this.memoryMessages.has(m)),
    v1: () => convertToV1Messages(this.remembered.v2()),
    aiV5: {
      model: () => this.aiV5UIMessagesToAIV5ModelMessages(this.remembered.aiV5.ui()),
      ui: () => this.remembered.v3().map(_MessageList.mastraMessageV3ToAIV5UIMessage)
    },
    /* @deprecated use list.get.remembered.aiV4.ui() */
    ui: () => this.remembered.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
    /* @deprecated use list.get.remembered.aiV4.core() */
    core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.all.aiV4.ui()),
    aiV4: {
      ui: () => this.remembered.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
      core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.all.aiV4.ui())
    }
  };
  // TODO: need to update this for new .aiV4/5.x() pattern
  rememberedPersisted = {
    v2: () => this.all.v2().filter((m) => this.memoryMessagesPersisted.has(m)),
    v1: () => convertToV1Messages(this.rememberedPersisted.v2()),
    ui: () => this.rememberedPersisted.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
    core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.rememberedPersisted.ui())
  };
  input = {
    v3: () => this.cleanV3Metadata(
      this.messages.filter((m) => this.newUserMessages.has(m)).map(this.mastraMessageV2ToMastraMessageV3)
    ),
    v2: () => this.messages.filter((m) => this.newUserMessages.has(m)),
    v1: () => convertToV1Messages(this.input.v2()),
    aiV5: {
      model: () => this.aiV5UIMessagesToAIV5ModelMessages(this.input.aiV5.ui()),
      ui: () => this.input.v3().map(_MessageList.mastraMessageV3ToAIV5UIMessage)
    },
    /* @deprecated use list.get.input.aiV4.ui() instead */
    ui: () => this.input.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
    /* @deprecated use list.get.core.aiV4.ui() instead */
    core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.input.ui()),
    aiV4: {
      ui: () => this.input.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
      core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.input.aiV4.ui())
    }
  };
  // TODO: need to update this for new .aiV4/5.x() pattern
  inputPersisted = {
    v3: () => this.cleanV3Metadata(
      this.messages.filter((m) => this.newUserMessagesPersisted.has(m)).map(this.mastraMessageV2ToMastraMessageV3)
    ),
    v2: () => this.messages.filter((m) => this.newUserMessagesPersisted.has(m)),
    v1: () => convertToV1Messages(this.inputPersisted.v2()),
    ui: () => this.inputPersisted.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
    core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.inputPersisted.ui())
  };
  response = {
    v3: () => this.response.v2().map(this.mastraMessageV2ToMastraMessageV3),
    v2: () => this.messages.filter((m) => this.newResponseMessages.has(m)),
    v1: () => convertToV1Messages(this.response.v3().map(_MessageList.mastraMessageV3ToV2)),
    aiV5: {
      ui: () => this.response.v3().map(_MessageList.mastraMessageV3ToAIV5UIMessage),
      model: () => this.aiV5UIMessagesToAIV5ModelMessages(this.response.aiV5.ui()).filter(
        (m) => m.role === `tool` || m.role === `assistant`
      ),
      modelContent: () => {
        return this.response.aiV5.model().map(this.response.aiV5.stepContent).flat();
      },
      stepContent: (message) => {
        const latest = message ? message : this.response.aiV5.model().at(-1);
        if (!latest) return [];
        if (typeof latest.content === `string`) {
          return [{ type: "text", text: latest.content }];
        }
        return latest.content.map((c) => {
          if (c.type === `tool-result`)
            return {
              type: "tool-result",
              input: {},
              // TODO: we need to find the tool call here and add the input from it
              output: c.output,
              toolCallId: c.toolCallId,
              toolName: c.toolName
            };
          if (c.type === `file`)
            return {
              type: "file",
              file: new DefaultGeneratedFileWithType({
                data: typeof c.data === `string` ? c.data : c.data instanceof URL ? c.data.toString() : convertDataContentToBase64String(c.data),
                mediaType: c.mediaType
              })
            };
          if (c.type === `image`) {
            return {
              type: "file",
              file: new DefaultGeneratedFileWithType({
                data: typeof c.image === `string` ? c.image : c.image instanceof URL ? c.image.toString() : convertDataContentToBase64String(c.image),
                mediaType: c.mediaType || "unknown"
              })
            };
          }
          return { ...c };
        });
      }
    },
    aiV4: {
      ui: () => this.response.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage),
      core: () => this.aiV4UIMessagesToAIV4CoreMessages(this.response.aiV4.ui())
    }
  };
  // TODO: need to update this for new .aiV4/5.x() pattern
  responsePersisted = {
    v3: () => this.cleanV3Metadata(
      this.messages.filter((m) => this.newResponseMessagesPersisted.has(m)).map(this.mastraMessageV2ToMastraMessageV3)
    ),
    v2: () => this.messages.filter((m) => this.newResponseMessagesPersisted.has(m)),
    ui: () => this.responsePersisted.v2().map(_MessageList.mastraMessageV2ToAIV4UIMessage)
  };
  drainUnsavedMessages() {
    const messages = this.messages.filter((m) => this.newUserMessages.has(m) || this.newResponseMessages.has(m));
    this.newUserMessages.clear();
    this.newResponseMessages.clear();
    return messages;
  }
  getEarliestUnsavedMessageTimestamp() {
    const unsavedMessages = this.messages.filter((m) => this.newUserMessages.has(m) || this.newResponseMessages.has(m));
    if (unsavedMessages.length === 0) return void 0;
    return Math.min(...unsavedMessages.map((m) => new Date(m.createdAt).getTime()));
  }
  getSystemMessages(tag) {
    if (tag) {
      return this.taggedSystemMessages[tag] || [];
    }
    return this.systemMessages;
  }
  addSystem(messages, tag) {
    if (!messages) return this;
    for (const message of Array.isArray(messages) ? messages : [messages]) {
      this.addOneSystem(message, tag);
    }
    return this;
  }
  aiV4UIMessagesToAIV4CoreMessages(messages) {
    return AIV4__namespace.convertToCoreMessages(this.sanitizeAIV4UIMessages(messages));
  }
  sanitizeAIV4UIMessages(messages) {
    const msgs = messages.map((m) => {
      if (m.parts.length === 0) return false;
      const safeParts = m.parts.filter(
        (p) => p.type !== `tool-invocation` || // calls and partial-calls should be updated to be results at this point
        // if they haven't we can't send them back to the llm and need to remove them.
        p.toolInvocation.state !== `call` && p.toolInvocation.state !== `partial-call`
      );
      if (!safeParts.length) return false;
      const sanitized = {
        ...m,
        parts: safeParts
      };
      if (`toolInvocations` in m && m.toolInvocations) {
        sanitized.toolInvocations = m.toolInvocations.filter((t) => t.state === `result`);
      }
      return sanitized;
    }).filter((m) => Boolean(m));
    return msgs;
  }
  addOneSystem(message, tag) {
    if (typeof message === `string`) message = { role: "system", content: message };
    const coreMessage = _MessageList.isAIV4CoreMessage(message) ? message : this.aiV5ModelMessagesToAIV4CoreMessages([message], `system`)[0];
    if (coreMessage.role !== `system`) {
      throw new Error(
        `Expected role "system" but saw ${coreMessage.role} for message ${JSON.stringify(coreMessage, null, 2)}`
      );
    }
    if (tag && !this.isDuplicateSystem(coreMessage, tag)) {
      this.taggedSystemMessages[tag] ||= [];
      this.taggedSystemMessages[tag].push(coreMessage);
    } else if (!this.isDuplicateSystem(coreMessage)) {
      this.systemMessages.push(coreMessage);
    }
  }
  isDuplicateSystem(message, tag) {
    if (tag) {
      if (!this.taggedSystemMessages[tag]) return false;
      return this.taggedSystemMessages[tag].some(
        (m) => _MessageList.cacheKeyFromAIV4CoreMessageContent(m.content) === _MessageList.cacheKeyFromAIV4CoreMessageContent(message.content)
      );
    }
    return this.systemMessages.some(
      (m) => _MessageList.cacheKeyFromAIV4CoreMessageContent(m.content) === _MessageList.cacheKeyFromAIV4CoreMessageContent(message.content)
    );
  }
  static mastraMessageV2ToAIV4UIMessage(m) {
    const experimentalAttachments = m.content.experimental_attachments ? [...m.content.experimental_attachments] : [];
    const contentString = typeof m.content.content === `string` && m.content.content !== "" ? m.content.content : m.content.parts.reduce((prev, part) => {
      if (part.type === `text`) {
        return part.text;
      }
      return prev;
    }, "");
    const parts = [];
    if (m.content.parts.length) {
      for (const part of m.content.parts) {
        if (part.type === `file`) {
          experimentalAttachments.push({
            contentType: part.mimeType,
            url: part.data
          });
        } else if (part.type === "tool-invocation" && (part.toolInvocation.state === "call" || part.toolInvocation.state === "partial-call")) {
          continue;
        } else if (part.type === "tool-invocation") {
          const toolInvocation = { ...part.toolInvocation };
          let currentStep = -1;
          let toolStep = -1;
          for (const innerPart of m.content.parts) {
            if (innerPart.type === `step-start`) currentStep++;
            if (innerPart.type === `tool-invocation` && innerPart.toolInvocation.toolCallId === part.toolInvocation.toolCallId) {
              toolStep = currentStep;
              break;
            }
          }
          if (toolStep >= 0) {
            const preparedInvocation = {
              step: toolStep,
              ...toolInvocation
            };
            parts.push({
              type: "tool-invocation",
              toolInvocation: preparedInvocation
            });
          } else {
            parts.push({
              type: "tool-invocation",
              toolInvocation
            });
          }
        } else {
          parts.push(part);
        }
      }
    }
    if (parts.length === 0 && experimentalAttachments.length > 0) {
      parts.push({ type: "text", text: "" });
    }
    if (m.role === `user`) {
      const uiMessage2 = {
        id: m.id,
        role: m.role,
        content: m.content.content || contentString,
        createdAt: m.createdAt,
        parts,
        experimental_attachments: experimentalAttachments
      };
      if (m.content.metadata) {
        uiMessage2.metadata = m.content.metadata;
      }
      return uiMessage2;
    } else if (m.role === `assistant`) {
      const isSingleTextContentArray = Array.isArray(m.content.content) && m.content.content.length === 1 && m.content.content[0].type === `text`;
      const uiMessage2 = {
        id: m.id,
        role: m.role,
        content: isSingleTextContentArray ? contentString : m.content.content || contentString,
        createdAt: m.createdAt,
        parts,
        reasoning: void 0,
        toolInvocations: `toolInvocations` in m.content ? m.content.toolInvocations?.filter((t) => t.state === "result") : void 0
      };
      if (m.content.metadata) {
        uiMessage2.metadata = m.content.metadata;
      }
      return uiMessage2;
    }
    const uiMessage = {
      id: m.id,
      role: m.role,
      content: m.content.content || contentString,
      createdAt: m.createdAt,
      parts,
      experimental_attachments: experimentalAttachments
    };
    if (m.content.metadata) {
      uiMessage.metadata = m.content.metadata;
    }
    return uiMessage;
  }
  getMessageById(id) {
    return this.messages.find((m) => m.id === id);
  }
  shouldReplaceMessage(message) {
    if (!this.messages.length) return { exists: false };
    if (!(`id` in message) || !message?.id) {
      return { exists: false };
    }
    const existingMessage = this.getMessageById(message.id);
    if (!existingMessage) return { exists: false };
    return {
      exists: true,
      shouldReplace: !_MessageList.messagesAreEqual(existingMessage, message),
      id: existingMessage.id
    };
  }
  addOne(message, messageSource) {
    if ((!(`content` in message) || !message.content && // allow empty strings
    typeof message.content !== "string") && (!(`parts` in message) || !message.parts)) {
      throw new chunkC73WLCY3_cjs.MastraError({
        id: "INVALID_MESSAGE_CONTENT",
        domain: "AGENT" /* AGENT */,
        category: "USER" /* USER */,
        text: `Message with role "${message.role}" must have either a 'content' property (string or array) or a 'parts' property (array) that is not empty, null, or undefined. Received message: ${JSON.stringify(message, null, 2)}`,
        details: {
          role: message.role,
          messageSource,
          hasContent: "content" in message,
          hasParts: "parts" in message
        }
      });
    }
    if (message.role === `system`) {
      if (messageSource === `memory`) return null;
      if (_MessageList.isAIV4CoreMessage(message) || _MessageList.isAIV5CoreMessage(message))
        return this.addSystem(message);
      throw new chunkC73WLCY3_cjs.MastraError({
        id: "INVALID_SYSTEM_MESSAGE_FORMAT",
        domain: "AGENT" /* AGENT */,
        category: "USER" /* USER */,
        text: `Invalid system message format. System messages must be CoreMessage format with 'role' and 'content' properties. The content should be a string or valid content array.`,
        details: {
          messageSource,
          receivedMessage: JSON.stringify(message, null, 2)
        }
      });
    }
    const messageV2 = this.inputToMastraMessageV2(message, messageSource);
    const { exists, shouldReplace, id } = this.shouldReplaceMessage(messageV2);
    const latestMessage = this.messages.at(-1);
    if (messageSource === `memory`) {
      for (const existingMessage of this.messages) {
        if (_MessageList.messagesAreEqual(existingMessage, messageV2)) {
          return;
        }
      }
    }
    const shouldAppendToLastAssistantMessage = latestMessage?.role === "assistant" && messageV2.role === "assistant" && latestMessage.threadId === messageV2.threadId && // If the message is from memory, don't append to the last assistant message
    messageSource !== "memory";
    const appendNetworkMessage = this._agentNetworkAppend && latestMessage && !this.memoryMessages.has(latestMessage) || !this._agentNetworkAppend;
    if (shouldAppendToLastAssistantMessage && appendNetworkMessage) {
      latestMessage.createdAt = messageV2.createdAt || latestMessage.createdAt;
      const toolResultAnchorMap = /* @__PURE__ */ new Map();
      const partsToAdd = /* @__PURE__ */ new Map();
      for (const [index, part] of messageV2.content.parts.entries()) {
        if (part.type === "tool-invocation") {
          const existingCallPart = [...latestMessage.content.parts].reverse().find((p) => p.type === "tool-invocation" && p.toolInvocation.toolCallId === part.toolInvocation.toolCallId);
          const existingCallToolInvocation = !!existingCallPart && existingCallPart.type === "tool-invocation";
          if (existingCallToolInvocation) {
            if (part.toolInvocation.state === "result") {
              existingCallPart.toolInvocation = {
                ...existingCallPart.toolInvocation,
                step: part.toolInvocation.step,
                state: "result",
                result: part.toolInvocation.result,
                args: {
                  ...existingCallPart.toolInvocation.args,
                  ...part.toolInvocation.args
                }
              };
              if (!latestMessage.content.toolInvocations) {
                latestMessage.content.toolInvocations = [];
              }
              const toolInvocationIndex = latestMessage.content.toolInvocations.findIndex(
                (t) => t.toolCallId === existingCallPart.toolInvocation.toolCallId
              );
              if (toolInvocationIndex === -1) {
                latestMessage.content.toolInvocations.push(existingCallPart.toolInvocation);
              } else {
                latestMessage.content.toolInvocations[toolInvocationIndex] = existingCallPart.toolInvocation;
              }
            }
            const existingIndex = latestMessage.content.parts.findIndex((p) => p === existingCallPart);
            toolResultAnchorMap.set(index, existingIndex);
          } else {
            partsToAdd.set(index, part);
          }
        } else {
          partsToAdd.set(index, part);
        }
      }
      this.addPartsToLatestMessage({
        latestMessage,
        messageV2,
        anchorMap: toolResultAnchorMap,
        partsToAdd
      });
      if (latestMessage.createdAt.getTime() < messageV2.createdAt.getTime()) {
        latestMessage.createdAt = messageV2.createdAt;
      }
      if (!latestMessage.content.content && messageV2.content.content) {
        latestMessage.content.content = messageV2.content.content;
      }
      if (latestMessage.content.content && messageV2.content.content && latestMessage.content.content !== messageV2.content.content) {
        latestMessage.content.content = messageV2.content.content;
      }
      this.pushMessageToSource(latestMessage, messageSource);
    } else {
      let existingIndex = -1;
      if (shouldReplace) {
        existingIndex = this.messages.findIndex((m) => m.id === id);
      }
      const existingMessage = existingIndex !== -1 && this.messages[existingIndex];
      if (shouldReplace && existingMessage) {
        this.messages[existingIndex] = messageV2;
      } else if (!exists) {
        this.messages.push(messageV2);
      }
      this.pushMessageToSource(messageV2, messageSource);
    }
    this.messages.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
    return this;
  }
  pushMessageToSource(messageV2, messageSource) {
    if (messageSource === `memory`) {
      this.memoryMessages.add(messageV2);
      this.memoryMessagesPersisted.add(messageV2);
    } else if (messageSource === `response`) {
      this.newResponseMessages.add(messageV2);
      this.newResponseMessagesPersisted.add(messageV2);
    } else if (messageSource === `input`) {
      this.newUserMessages.add(messageV2);
      this.newUserMessagesPersisted.add(messageV2);
    } else if (messageSource === `context`) {
      this.userContextMessages.add(messageV2);
      this.userContextMessagesPersisted.add(messageV2);
    } else {
      throw new Error(`Missing message source for message ${messageV2}`);
    }
  }
  /**
   * Pushes a new message part to the latest message.
   * @param latestMessage - The latest message to push the part to.
   * @param newMessage - The new message to push the part from.
   * @param part - The part to push.
   * @param insertAt - The index at which to insert the part. Optional.
   */
  pushNewMessagePart({
    latestMessage,
    newMessage,
    part,
    insertAt
    // optional
  }) {
    const partKey = _MessageList.cacheKeyFromAIV4Parts([part]);
    const latestPartCount = latestMessage.content.parts.filter(
      (p) => _MessageList.cacheKeyFromAIV4Parts([p]) === partKey
    ).length;
    const newPartCount = newMessage.content.parts.filter(
      (p) => _MessageList.cacheKeyFromAIV4Parts([p]) === partKey
    ).length;
    if (latestPartCount < newPartCount) {
      const partIndex = newMessage.content.parts.indexOf(part);
      const hasStepStartBefore = partIndex > 0 && newMessage.content.parts[partIndex - 1]?.type === "step-start";
      const needsStepStart = latestMessage.role === "assistant" && part.type === "text" && !hasStepStartBefore && latestMessage.content.parts.length > 0 && latestMessage.content.parts.at(-1)?.type === "tool-invocation";
      if (typeof insertAt === "number") {
        if (needsStepStart) {
          latestMessage.content.parts.splice(insertAt, 0, { type: "step-start" });
          latestMessage.content.parts.splice(insertAt + 1, 0, part);
        } else {
          latestMessage.content.parts.splice(insertAt, 0, part);
        }
      } else {
        if (needsStepStart) {
          latestMessage.content.parts.push({ type: "step-start" });
        }
        latestMessage.content.parts.push(part);
      }
    }
  }
  /**
   * Upserts parts of messageV2 into latestMessage based on the anchorMap.
   * This is used when appending a message to the last assistant message to ensure that parts are inserted in the correct order.
   * @param latestMessage - The latest message to upsert parts into.
   * @param messageV2 - The message to upsert parts from.
   * @param anchorMap - The anchor map to use for upserting parts.
   */
  addPartsToLatestMessage({
    latestMessage,
    messageV2,
    anchorMap,
    partsToAdd
  }) {
    for (let i = 0; i < messageV2.content.parts.length; ++i) {
      const part = messageV2.content.parts[i];
      if (!part) continue;
      const key = _MessageList.cacheKeyFromAIV4Parts([part]);
      const partToAdd = partsToAdd.get(i);
      if (!key || !partToAdd) continue;
      if (anchorMap.size > 0) {
        if (anchorMap.has(i)) continue;
        const leftAnchorV2 = [...anchorMap.keys()].filter((idx) => idx < i).pop() ?? -1;
        const rightAnchorV2 = [...anchorMap.keys()].find((idx) => idx > i) ?? -1;
        const leftAnchorLatest = leftAnchorV2 !== -1 ? anchorMap.get(leftAnchorV2) : 0;
        const offset = leftAnchorV2 === -1 ? i : i - leftAnchorV2;
        const insertAt = leftAnchorLatest + offset;
        const rightAnchorLatest = rightAnchorV2 !== -1 ? anchorMap.get(rightAnchorV2) : latestMessage.content.parts.length;
        if (insertAt >= 0 && insertAt <= rightAnchorLatest && !latestMessage.content.parts.slice(insertAt, rightAnchorLatest).some((p) => _MessageList.cacheKeyFromAIV4Parts([p]) === _MessageList.cacheKeyFromAIV4Parts([part]))) {
          this.pushNewMessagePart({
            latestMessage,
            newMessage: messageV2,
            part,
            insertAt
          });
          for (const [v2Idx, latestIdx] of anchorMap.entries()) {
            if (latestIdx >= insertAt) {
              anchorMap.set(v2Idx, latestIdx + 1);
            }
          }
        }
      } else {
        this.pushNewMessagePart({
          latestMessage,
          newMessage: messageV2,
          part
        });
      }
    }
  }
  inputToMastraMessageV2(message, messageSource) {
    if (
      // we can't throw if the threadId doesn't match and this message came from memory
      // this is because per-user semantic recall can retrieve messages from other threads
      messageSource !== `memory` && `threadId` in message && message.threadId && this.memoryInfo && message.threadId !== this.memoryInfo.threadId
    ) {
      throw new Error(
        `Received input message with wrong threadId. Input ${message.threadId}, expected ${this.memoryInfo.threadId}`
      );
    }
    if (`resourceId` in message && message.resourceId && this.memoryInfo?.resourceId && message.resourceId !== this.memoryInfo.resourceId) {
      throw new Error(
        `Received input message with wrong resourceId. Input ${message.resourceId}, expected ${this.memoryInfo.resourceId}`
      );
    }
    if (_MessageList.isMastraMessageV1(message)) {
      return this.mastraMessageV1ToMastraMessageV2(message, messageSource);
    }
    if (_MessageList.isMastraMessageV2(message)) {
      return this.hydrateMastraMessageV2Fields(message);
    }
    if (_MessageList.isAIV4CoreMessage(message)) {
      return this.aiV4CoreMessageToMastraMessageV2(message, messageSource);
    }
    if (_MessageList.isAIV4UIMessage(message)) {
      return this.aiV4UIMessageToMastraMessageV2(message, messageSource);
    }
    if (_MessageList.isAIV5CoreMessage(message)) {
      return _MessageList.mastraMessageV3ToV2(this.aiV5ModelMessageToMastraMessageV3(message, messageSource));
    }
    if (_MessageList.isAIV5UIMessage(message)) {
      return _MessageList.mastraMessageV3ToV2(this.aiV5UIMessageToMastraMessageV3(message, messageSource));
    }
    if (_MessageList.isMastraMessageV3(message)) {
      return _MessageList.mastraMessageV3ToV2(this.hydrateMastraMessageV3Fields(message));
    }
    throw new Error(`Found unhandled message ${JSON.stringify(message)}`);
  }
  lastCreatedAt;
  // this makes sure messages added in order will always have a date atleast 1ms apart.
  generateCreatedAt(messageSource, start) {
    start = start instanceof Date ? start : start ? new Date(start) : void 0;
    if (start && !this.lastCreatedAt) {
      this.lastCreatedAt = start.getTime();
      return start;
    }
    if (start && messageSource === `memory`) {
      return start;
    }
    const now = /* @__PURE__ */ new Date();
    const nowTime = start?.getTime() || now.getTime();
    const lastTime = this.messages.reduce((p, m) => {
      if (m.createdAt.getTime() > p) return m.createdAt.getTime();
      return p;
    }, this.lastCreatedAt || 0);
    if (nowTime <= lastTime) {
      const newDate = new Date(lastTime + 1);
      this.lastCreatedAt = newDate.getTime();
      return newDate;
    }
    this.lastCreatedAt = nowTime;
    return now;
  }
  newMessageId() {
    if (this.generateMessageId) {
      return this.generateMessageId();
    }
    return crypto.randomUUID();
  }
  mastraMessageV1ToMastraMessageV2(message, messageSource) {
    const coreV2 = this.aiV4CoreMessageToMastraMessageV2(
      {
        content: message.content,
        role: message.role
      },
      messageSource
    );
    return {
      id: message.id,
      role: coreV2.role,
      createdAt: this.generateCreatedAt(messageSource, message.createdAt),
      threadId: message.threadId,
      resourceId: message.resourceId,
      content: coreV2.content
    };
  }
  hydrateMastraMessageV3Fields(message) {
    if (!(message.createdAt instanceof Date)) message.createdAt = new Date(message.createdAt);
    return message;
  }
  hydrateMastraMessageV2Fields(message) {
    if (!(message.createdAt instanceof Date)) message.createdAt = new Date(message.createdAt);
    if (message.content.toolInvocations && message.content.parts) {
      message.content.toolInvocations = message.content.toolInvocations.map((ti) => {
        if (!ti.args || Object.keys(ti.args).length === 0) {
          const partWithArgs = message.content.parts.find(
            (part) => part.type === "tool-invocation" && part.toolInvocation && part.toolInvocation.toolCallId === ti.toolCallId && part.toolInvocation.args && Object.keys(part.toolInvocation.args).length > 0
          );
          if (partWithArgs && partWithArgs.type === "tool-invocation") {
            return { ...ti, args: partWithArgs.toolInvocation.args };
          }
        }
        return ti;
      });
    }
    return message;
  }
  aiV4UIMessageToMastraMessageV2(message, messageSource) {
    const content = {
      format: 2,
      parts: message.parts
    };
    if (message.toolInvocations) content.toolInvocations = message.toolInvocations;
    if (message.reasoning) content.reasoning = message.reasoning;
    if (message.annotations) content.annotations = message.annotations;
    if (message.experimental_attachments) {
      content.experimental_attachments = message.experimental_attachments;
    }
    if ("metadata" in message && message.metadata !== null && message.metadata !== void 0) {
      content.metadata = message.metadata;
    }
    return {
      id: message.id || this.newMessageId(),
      role: _MessageList.getRole(message),
      createdAt: this.generateCreatedAt(messageSource, message.createdAt),
      threadId: this.memoryInfo?.threadId,
      resourceId: this.memoryInfo?.resourceId,
      content
    };
  }
  aiV4CoreMessageToMastraMessageV2(coreMessage, messageSource) {
    const id = `id` in coreMessage ? coreMessage.id : this.newMessageId();
    const parts = [];
    const experimentalAttachments = [];
    const toolInvocations = [];
    const isSingleTextContent = messageSource === `response` && Array.isArray(coreMessage.content) && coreMessage.content.length === 1 && coreMessage.content[0] && coreMessage.content[0].type === `text` && `text` in coreMessage.content[0] && coreMessage.content[0].text;
    if (isSingleTextContent && messageSource === `response`) {
      coreMessage.content = isSingleTextContent;
    }
    if (typeof coreMessage.content === "string") {
      parts.push({
        type: "text",
        text: coreMessage.content
      });
    } else if (Array.isArray(coreMessage.content)) {
      for (const part of coreMessage.content) {
        switch (part.type) {
          case "text":
            const prevPart = parts.at(-1);
            if (coreMessage.role === "assistant" && prevPart && prevPart.type === "tool-invocation") {
              parts.push({ type: "step-start" });
            }
            parts.push({
              type: "text",
              text: part.text
            });
            break;
          case "tool-call":
            parts.push({
              type: "tool-invocation",
              toolInvocation: {
                state: "call",
                toolCallId: part.toolCallId,
                toolName: part.toolName,
                args: part.args
              }
            });
            break;
          case "tool-result":
            let toolArgs = {};
            const toolCallInSameMsg = coreMessage.content.find(
              (p) => p.type === "tool-call" && p.toolCallId === part.toolCallId
            );
            if (toolCallInSameMsg && toolCallInSameMsg.type === "tool-call") {
              toolArgs = toolCallInSameMsg.args;
            }
            if (Object.keys(toolArgs).length === 0) {
              for (let i = this.messages.length - 1; i >= 0; i--) {
                const msg = this.messages[i];
                if (msg && msg.role === "assistant" && msg.content.parts) {
                  const toolCallPart = msg.content.parts.find(
                    (p) => p.type === "tool-invocation" && p.toolInvocation.toolCallId === part.toolCallId && p.toolInvocation.state === "call"
                  );
                  if (toolCallPart && toolCallPart.type === "tool-invocation" && toolCallPart.toolInvocation.args) {
                    toolArgs = toolCallPart.toolInvocation.args;
                    break;
                  }
                }
              }
            }
            const invocation = {
              state: "result",
              toolCallId: part.toolCallId,
              toolName: part.toolName,
              result: part.result ?? "",
              // undefined will cause AI SDK to throw an error, but for client side tool calls this really could be undefined
              args: toolArgs
              // Use the args from the corresponding tool-call
            };
            parts.push({
              type: "tool-invocation",
              toolInvocation: invocation
            });
            toolInvocations.push(invocation);
            break;
          case "reasoning":
            parts.push({
              type: "reasoning",
              reasoning: "",
              // leave this blank so we aren't double storing it in the db along with details
              details: [{ type: "text", text: part.text, signature: part.signature }]
            });
            break;
          case "redacted-reasoning":
            parts.push({
              type: "reasoning",
              reasoning: "",
              // No text reasoning for redacted parts
              details: [{ type: "redacted", data: part.data }]
            });
            break;
          case "image":
            parts.push({ type: "file", data: part.image.toString(), mimeType: part.mimeType });
            break;
          case "file":
            if (part.data instanceof URL) {
              parts.push({
                type: "file",
                data: part.data.toString(),
                mimeType: part.mimeType
              });
            } else {
              try {
                parts.push({
                  type: "file",
                  mimeType: part.mimeType,
                  data: convertDataContentToBase64String(part.data)
                });
              } catch (error) {
                console.error(`Failed to convert binary data to base64 in CoreMessage file part: ${error}`, error);
              }
            }
            break;
        }
      }
    }
    const content = {
      format: 2,
      parts
    };
    if (toolInvocations.length) content.toolInvocations = toolInvocations;
    if (typeof coreMessage.content === `string`) content.content = coreMessage.content;
    if (experimentalAttachments.length) content.experimental_attachments = experimentalAttachments;
    return {
      id,
      role: _MessageList.getRole(coreMessage),
      createdAt: this.generateCreatedAt(messageSource),
      threadId: this.memoryInfo?.threadId,
      resourceId: this.memoryInfo?.resourceId,
      content
    };
  }
  static isAIV4UIMessage(msg) {
    return !_MessageList.isMastraMessage(msg) && !_MessageList.isAIV4CoreMessage(msg) && `parts` in msg && !_MessageList.hasAIV5UIMessageCharacteristics(msg);
  }
  static isAIV5CoreMessage(msg) {
    return !_MessageList.isMastraMessage(msg) && !(`parts` in msg) && `content` in msg && _MessageList.hasAIV5CoreMessageCharacteristics(msg);
  }
  static isAIV4CoreMessage(msg) {
    return !_MessageList.isMastraMessage(msg) && !(`parts` in msg) && `content` in msg && !_MessageList.hasAIV5CoreMessageCharacteristics(msg);
  }
  static isMastraMessage(msg) {
    return _MessageList.isMastraMessageV3(msg) || _MessageList.isMastraMessageV2(msg) || _MessageList.isMastraMessageV1(msg);
  }
  static isMastraMessageV1(msg) {
    return !_MessageList.isMastraMessageV2(msg) && !_MessageList.isMastraMessageV3(msg) && (`threadId` in msg || `resourceId` in msg);
  }
  static isMastraMessageV2(msg) {
    return Boolean(
      `content` in msg && msg.content && !Array.isArray(msg.content) && typeof msg.content !== `string` && `format` in msg.content && msg.content.format === 2
    );
  }
  static isMastraMessageV3(msg) {
    return Boolean(
      `content` in msg && msg.content && !Array.isArray(msg.content) && typeof msg.content !== `string` && `format` in msg.content && msg.content.format === 3
    );
  }
  static getRole(message) {
    if (message.role === `assistant` || message.role === `tool`) return `assistant`;
    if (message.role === `user`) return `user`;
    if (message.role === `system`) return `system`;
    throw new Error(
      `BUG: add handling for message role ${message.role} in message ${JSON.stringify(message, null, 2)}`
    );
  }
  static cacheKeyFromAIV4Parts(parts) {
    let key = ``;
    for (const part of parts) {
      key += part.type;
      if (part.type === `text`) {
        key += part.text;
      }
      if (part.type === `tool-invocation`) {
        key += part.toolInvocation.toolCallId;
        key += part.toolInvocation.state;
      }
      if (part.type === `reasoning`) {
        key += part.reasoning;
        key += part.details.reduce((prev, current) => {
          if (current.type === `text`) {
            return prev + current.text.length + (current.signature?.length || 0);
          }
          return prev;
        }, 0);
      }
      if (part.type === `file`) {
        key += part.data;
        key += part.mimeType;
      }
    }
    return key;
  }
  static coreContentToString(content) {
    if (typeof content === `string`) return content;
    return content.reduce((p, c) => {
      if (c.type === `text`) {
        p += c.text;
      }
      return p;
    }, "");
  }
  static cacheKeyFromAIV4CoreMessageContent(content) {
    if (typeof content === `string`) return content;
    let key = ``;
    for (const part of content) {
      key += part.type;
      if (part.type === `text`) {
        key += part.text.length;
      }
      if (part.type === `reasoning`) {
        key += part.text.length;
      }
      if (part.type === `tool-call`) {
        key += part.toolCallId;
        key += part.toolName;
      }
      if (part.type === `tool-result`) {
        key += part.toolCallId;
        key += part.toolName;
      }
      if (part.type === `file`) {
        key += part.filename;
        key += part.mimeType;
      }
      if (part.type === `image`) {
        key += part.image instanceof URL ? part.image.toString() : part.image.toString().length;
        key += part.mimeType;
      }
      if (part.type === `redacted-reasoning`) {
        key += part.data.length;
      }
    }
    return key;
  }
  static messagesAreEqual(one, two) {
    const oneUIV4 = _MessageList.isAIV4UIMessage(one) && one;
    const twoUIV4 = _MessageList.isAIV4UIMessage(two) && two;
    if (oneUIV4 && !twoUIV4) return false;
    if (oneUIV4 && twoUIV4) {
      return _MessageList.cacheKeyFromAIV4Parts(one.parts) === _MessageList.cacheKeyFromAIV4Parts(two.parts);
    }
    const oneCMV4 = _MessageList.isAIV4CoreMessage(one) && one;
    const twoCMV4 = _MessageList.isAIV4CoreMessage(two) && two;
    if (oneCMV4 && !twoCMV4) return false;
    if (oneCMV4 && twoCMV4) {
      return _MessageList.cacheKeyFromAIV4CoreMessageContent(oneCMV4.content) === _MessageList.cacheKeyFromAIV4CoreMessageContent(twoCMV4.content);
    }
    const oneMM1 = _MessageList.isMastraMessageV1(one) && one;
    const twoMM1 = _MessageList.isMastraMessageV1(two) && two;
    if (oneMM1 && !twoMM1) return false;
    if (oneMM1 && twoMM1) {
      return oneMM1.id === twoMM1.id && _MessageList.cacheKeyFromAIV4CoreMessageContent(oneMM1.content) === _MessageList.cacheKeyFromAIV4CoreMessageContent(twoMM1.content);
    }
    const oneMM2 = _MessageList.isMastraMessageV2(one) && one;
    const twoMM2 = _MessageList.isMastraMessageV2(two) && two;
    if (oneMM2 && !twoMM2) return false;
    if (oneMM2 && twoMM2) {
      return oneMM2.id === twoMM2.id && _MessageList.cacheKeyFromAIV4Parts(oneMM2.content.parts) === _MessageList.cacheKeyFromAIV4Parts(twoMM2.content.parts);
    }
    const oneMM3 = _MessageList.isMastraMessageV3(one) && one;
    const twoMM3 = _MessageList.isMastraMessageV3(two) && two;
    if (oneMM3 && !twoMM3) return false;
    if (oneMM3 && twoMM3) {
      return oneMM3.id === twoMM3.id && _MessageList.cacheKeyFromAIV5Parts(oneMM3.content.parts) === _MessageList.cacheKeyFromAIV5Parts(twoMM3.content.parts);
    }
    const oneUIV5 = _MessageList.isAIV5UIMessage(one) && one;
    const twoUIV5 = _MessageList.isAIV5UIMessage(two) && two;
    if (oneUIV5 && !twoUIV5) return false;
    if (oneUIV5 && twoUIV5) {
      return _MessageList.cacheKeyFromAIV5Parts(one.parts) === _MessageList.cacheKeyFromAIV5Parts(two.parts);
    }
    const oneCMV5 = _MessageList.isAIV5CoreMessage(one) && one;
    const twoCMV5 = _MessageList.isAIV5CoreMessage(two) && two;
    if (oneCMV5 && !twoCMV5) return false;
    if (oneCMV5 && twoCMV5) {
      return _MessageList.cacheKeyFromAIV5ModelMessageContent(oneCMV5.content) === _MessageList.cacheKeyFromAIV5ModelMessageContent(twoCMV5.content);
    }
    return true;
  }
  cleanV3Metadata(messages) {
    return messages.map((msg) => {
      if (!msg.content.metadata || typeof msg.content.metadata !== "object") {
        return msg;
      }
      const metadata = { ...msg.content.metadata };
      const hasOriginalContent = "__originalContent" in metadata;
      const hasOriginalAttachments = "__originalExperimentalAttachments" in metadata;
      if (!hasOriginalContent && !hasOriginalAttachments) {
        return msg;
      }
      const { __originalContent, __originalExperimentalAttachments, ...cleanMetadata } = metadata;
      if (Object.keys(cleanMetadata).length === 0) {
        const { metadata: metadata2, ...contentWithoutMetadata } = msg.content;
        return { ...msg, content: contentWithoutMetadata };
      }
      return { ...msg, content: { ...msg.content, metadata: cleanMetadata } };
    });
  }
  static aiV4CoreMessageToV1PromptMessage(coreMessage) {
    if (coreMessage.role === `system`) {
      return coreMessage;
    }
    if (typeof coreMessage.content === `string` && (coreMessage.role === `assistant` || coreMessage.role === `user`)) {
      return {
        ...coreMessage,
        content: [{ type: "text", text: coreMessage.content }]
      };
    }
    if (typeof coreMessage.content === `string`) {
      throw new Error(
        `Saw text content for input CoreMessage, but the role is ${coreMessage.role}. This is only allowed for "system", "assistant", and "user" roles.`
      );
    }
    const roleContent = {
      user: [],
      assistant: [],
      tool: []
    };
    const role = coreMessage.role;
    for (const part of coreMessage.content) {
      const incompatibleMessage = `Saw incompatible message content part type ${part.type} for message role ${role}`;
      switch (part.type) {
        case "text": {
          if (role === `tool`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push(part);
          break;
        }
        case "redacted-reasoning":
        case "reasoning": {
          if (role !== `assistant`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push(part);
          break;
        }
        case "tool-call": {
          if (role === `tool` || role === `user`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push(part);
          break;
        }
        case "tool-result": {
          if (role === `assistant` || role === `user`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push(part);
          break;
        }
        case "image": {
          if (role === `tool` || role === `assistant`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push({
            ...part,
            image: part.image instanceof URL || part.image instanceof Uint8Array ? part.image : Buffer.isBuffer(part.image) || part.image instanceof ArrayBuffer ? new Uint8Array(part.image) : new URL(part.image)
          });
          break;
        }
        case "file": {
          if (role === `tool`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push({
            ...part,
            data: part.data instanceof URL ? part.data : typeof part.data === "string" ? part.data : convertDataContentToBase64String(part.data)
          });
          break;
        }
      }
    }
    if (role === `tool`) {
      return {
        ...coreMessage,
        content: roleContent[role]
      };
    }
    if (role === `user`) {
      return {
        ...coreMessage,
        content: roleContent[role]
      };
    }
    if (role === `assistant`) {
      return {
        ...coreMessage,
        content: roleContent[role]
      };
    }
    throw new Error(
      `Encountered unknown role ${role} when converting V4 CoreMessage -> V4 LanguageModelV1Prompt, input message: ${JSON.stringify(coreMessage, null, 2)}`
    );
  }
  static aiV5ModelMessageToV2PromptMessage(modelMessage) {
    if (modelMessage.role === `system`) {
      return modelMessage;
    }
    if (typeof modelMessage.content === `string` && (modelMessage.role === `assistant` || modelMessage.role === `user`)) {
      return {
        role: modelMessage.role,
        content: [{ type: "text", text: modelMessage.content }],
        providerOptions: modelMessage.providerOptions
      };
    }
    if (typeof modelMessage.content === `string`) {
      throw new Error(
        `Saw text content for input ModelMessage, but the role is ${modelMessage.role}. This is only allowed for "system", "assistant", and "user" roles.`
      );
    }
    const roleContent = {
      user: [],
      assistant: [],
      tool: []
    };
    const role = modelMessage.role;
    for (const part of modelMessage.content) {
      const incompatibleMessage = `Saw incompatible message content part type ${part.type} for message role ${role}`;
      switch (part.type) {
        case "text": {
          if (role === `tool`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push(part);
          break;
        }
        case "reasoning": {
          if (role === `tool` || role === `user`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push(part);
          break;
        }
        case "tool-call": {
          if (role !== `assistant`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push(part);
          break;
        }
        case "tool-result": {
          if (role === `assistant` || role === `user`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push(part);
          break;
        }
        case "file": {
          if (role === `tool`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push({
            ...part,
            data: part.data instanceof ArrayBuffer ? new Uint8Array(part.data) : part.data
          });
          break;
        }
        case "image": {
          if (role === `tool`) {
            throw new Error(incompatibleMessage);
          }
          roleContent[role].push({
            ...part,
            mediaType: part.mediaType || "image/unknown",
            type: "file",
            data: part.image instanceof ArrayBuffer ? new Uint8Array(part.image) : part.image
          });
          break;
        }
      }
    }
    if (role === `tool`) {
      return {
        ...modelMessage,
        content: roleContent[role]
      };
    }
    if (role === `user`) {
      return {
        ...modelMessage,
        content: roleContent[role]
      };
    }
    if (role === `assistant`) {
      return {
        ...modelMessage,
        content: roleContent[role]
      };
    }
    throw new Error(
      `Encountered unknown role ${role} when converting V5 ModelMessage -> V5 LanguageModelV2Message, input message: ${JSON.stringify(modelMessage, null, 2)}`
    );
  }
  static mastraMessageV3ToV2(v3Msg) {
    const toolInvocationParts = v3Msg.content.parts.filter((p) => AIV5__namespace.isToolUIPart(p));
    const hadToolInvocations = v3Msg.content.metadata?.__hadToolInvocations === true;
    let toolInvocations = void 0;
    if (toolInvocationParts.length > 0) {
      const invocations = toolInvocationParts.map((p) => {
        const toolName = getToolName(p);
        if (p.state === `output-available`) {
          return {
            args: p.input,
            result: typeof p.output === "object" && p.output && "value" in p.output ? p.output.value : p.output,
            toolCallId: p.toolCallId,
            toolName,
            state: "result"
          };
        }
        return {
          args: p.input,
          state: "call",
          toolName,
          toolCallId: p.toolCallId
        };
      });
      toolInvocations = invocations;
    } else if (hadToolInvocations && v3Msg.role === "assistant") {
      toolInvocations = [];
    }
    const attachmentUrls = new Set(v3Msg.content.metadata?.__attachmentUrls || []);
    const v2Msg = {
      id: v3Msg.id,
      resourceId: v3Msg.resourceId,
      threadId: v3Msg.threadId,
      createdAt: v3Msg.createdAt,
      role: v3Msg.role,
      content: {
        format: 2,
        parts: v3Msg.content.parts.map((p) => {
          if (AIV5__namespace.isToolUIPart(p) || p.type === "dynamic-tool") {
            const toolName = getToolName(p);
            const shared = {
              state: p.state,
              args: p.input,
              toolCallId: p.toolCallId,
              toolName
            };
            if (p.state === `output-available`) {
              return {
                type: "tool-invocation",
                toolInvocation: {
                  ...shared,
                  state: "result",
                  result: typeof p.output === "object" && p.output && "value" in p.output ? p.output.value : p.output
                },
                providerMetadata: p.callProviderMetadata
              };
            }
            return {
              type: "tool-invocation",
              toolInvocation: {
                ...shared,
                state: p.state === `input-available` ? `call` : `partial-call`
              }
            };
          }
          switch (p.type) {
            case "text":
              return p;
            case "file":
              if (attachmentUrls.has(p.url)) {
                return null;
              }
              return {
                type: "file",
                mimeType: p.mediaType,
                data: p.url,
                providerMetadata: p.providerMetadata
              };
            case "reasoning":
              if (p.text === "") return null;
              return {
                type: "reasoning",
                reasoning: p.text,
                details: [{ type: "text", text: p.text }],
                providerMetadata: p.providerMetadata
              };
            case "source-url":
              return {
                type: "source",
                source: {
                  url: p.url,
                  id: p.sourceId,
                  sourceType: "url"
                },
                providerMetadata: p.providerMetadata
              };
            case "step-start":
              return p;
          }
          return null;
        }).filter((p) => Boolean(p))
      }
    };
    if (toolInvocations !== void 0) {
      v2Msg.content.toolInvocations = toolInvocations;
    }
    if (v3Msg.content.metadata) {
      const { __originalContent, __originalExperimentalAttachments, __attachmentUrls, ...userMetadata } = v3Msg.content.metadata;
      v2Msg.content.metadata = userMetadata;
    }
    const originalContent = v3Msg.content.metadata?.__originalContent;
    if (originalContent !== void 0) {
      if (typeof originalContent !== `string` || v2Msg.content.parts.every((p) => p.type === `step-start` || p.type === `text`)) {
        v2Msg.content.content = originalContent;
      }
    }
    const originalAttachments = v3Msg.content.metadata?.__originalExperimentalAttachments;
    if (originalAttachments && Array.isArray(originalAttachments)) {
      v2Msg.content.experimental_attachments = originalAttachments || [];
    }
    if (toolInvocations && toolInvocations.length > 0) {
      const resultToolInvocations = toolInvocations.filter((t) => t.state === "result");
      if (resultToolInvocations.length > 0) {
        v2Msg.content.toolInvocations = resultToolInvocations;
      }
    }
    if (v3Msg.type) v2Msg.type = v3Msg.type;
    return v2Msg;
  }
  mastraMessageV2ToMastraMessageV3(v2Msg) {
    const parts = [];
    const v3Msg = {
      id: v2Msg.id,
      content: {
        format: 3,
        parts
      },
      role: v2Msg.role,
      createdAt: v2Msg.createdAt instanceof Date ? v2Msg.createdAt : new Date(v2Msg.createdAt),
      resourceId: v2Msg.resourceId,
      threadId: v2Msg.threadId,
      type: v2Msg.type
    };
    if (v2Msg.content.metadata) {
      v3Msg.content.metadata = { ...v2Msg.content.metadata };
    }
    if (v2Msg.content.content !== void 0) {
      v3Msg.content.metadata = {
        ...v3Msg.content.metadata || {},
        __originalContent: v2Msg.content.content
      };
    }
    if (v2Msg.content.experimental_attachments !== void 0) {
      v3Msg.content.metadata = {
        ...v3Msg.content.metadata || {},
        __originalExperimentalAttachments: v2Msg.content.experimental_attachments
      };
    }
    const fileUrls = /* @__PURE__ */ new Set();
    for (const part of v2Msg.content.parts) {
      switch (part.type) {
        case "step-start":
        case "text":
          parts.push(part);
          break;
        case "tool-invocation":
          if (part.toolInvocation.state === `result`) {
            parts.push({
              type: `tool-${part.toolInvocation.toolName}`,
              toolCallId: part.toolInvocation.toolCallId,
              state: "output-available",
              input: part.toolInvocation.args,
              output: part.toolInvocation.result,
              callProviderMetadata: part.providerMetadata
            });
          } else {
            parts.push({
              type: `tool-${part.toolInvocation.toolName}`,
              toolCallId: part.toolInvocation.toolCallId,
              state: part.toolInvocation.state === `call` ? `input-available` : `input-streaming`,
              input: part.toolInvocation.args
            });
          }
          break;
        case "source":
          parts.push({
            type: "source-url",
            sourceId: part.source.id,
            url: part.source.url,
            title: part.source.title,
            providerMetadata: part.source.providerMetadata || part.providerMetadata
          });
          break;
        case "reasoning":
          const text = part.reasoning || (part.details?.reduce((p, c) => {
            if (c.type === `text`) return p + c.text;
            return p;
          }, "") ?? "");
          if (text || part.details?.length) {
            parts.push({
              type: "reasoning",
              text: text || "",
              state: "done",
              providerMetadata: part.providerMetadata
            });
          }
          break;
        case "file":
          parts.push({
            type: "file",
            url: part.data,
            mediaType: part.mimeType,
            providerMetadata: part.providerMetadata
          });
          fileUrls.add(part.data);
          break;
      }
    }
    if (v2Msg.content.content && !v3Msg.content.parts?.some((p) => p.type === `text`)) {
      v3Msg.content.parts.push({ type: "text", text: v2Msg.content.content });
    }
    const attachmentUrls = [];
    if (v2Msg.content.experimental_attachments?.length) {
      for (const attachment of v2Msg.content.experimental_attachments) {
        if (fileUrls.has(attachment.url)) continue;
        attachmentUrls.push(attachment.url);
        parts.push({
          url: attachment.url,
          mediaType: attachment.contentType || "unknown",
          type: "file"
        });
      }
    }
    if (attachmentUrls.length > 0) {
      v3Msg.content.metadata = {
        ...v3Msg.content.metadata || {},
        __attachmentUrls: attachmentUrls
      };
    }
    return v3Msg;
  }
  aiV5UIMessagesToAIV5ModelMessages(messages) {
    return AIV5__namespace.convertToModelMessages(this.addStartStepPartsForAIV5(this.sanitizeV5UIMessages(messages)));
  }
  addStartStepPartsForAIV5(messages) {
    for (const message of messages) {
      if (message.role !== `assistant`) continue;
      for (const [index, part] of message.parts.entries()) {
        if (!AIV5__namespace.isToolUIPart(part)) continue;
        if (message.parts.at(index + 1)?.type !== `step-start`) {
          message.parts.splice(index + 1, 0, { type: "step-start" });
        }
      }
    }
    return messages;
  }
  sanitizeV5UIMessages(messages) {
    const msgs = messages.map((m) => {
      if (m.parts.length === 0) return false;
      const safeParts = m.parts.filter((p) => {
        if (!AIV5__namespace.isToolUIPart(p)) return true;
        return p.state === "output-available" || p.state === "output-error";
      });
      if (!safeParts.length) return false;
      const sanitized = {
        ...m,
        parts: safeParts.map((part) => {
          if (AIV5__namespace.isToolUIPart(part) && part.state === "output-available") {
            return {
              ...part,
              output: typeof part.output === "object" && part.output && "value" in part.output ? part.output.value : part.output
            };
          }
          return part;
        })
      };
      return sanitized;
    }).filter((m) => Boolean(m));
    return msgs;
  }
  static mastraMessageV3ToAIV5UIMessage(m) {
    const metadata = {
      ...m.content.metadata || {}
    };
    if (m.createdAt) metadata.createdAt = m.createdAt;
    if (m.threadId) metadata.threadId = m.threadId;
    if (m.resourceId) metadata.resourceId = m.resourceId;
    const filteredParts = m.content.parts;
    return {
      id: m.id,
      role: m.role,
      metadata,
      parts: filteredParts
    };
  }
  aiV5ModelMessagesToAIV4CoreMessages(messages, messageSource) {
    const v3 = messages.map((msg) => this.aiV5ModelMessageToMastraMessageV3(msg, messageSource));
    const v2 = v3.map(_MessageList.mastraMessageV3ToV2);
    const ui = v2.map(_MessageList.mastraMessageV2ToAIV4UIMessage);
    const core = this.aiV4UIMessagesToAIV4CoreMessages(ui);
    return core;
  }
  aiV4CoreMessagesToAIV5ModelMessages(messages, source) {
    return this.aiV5UIMessagesToAIV5ModelMessages(
      messages.map((m) => this.aiV4CoreMessageToMastraMessageV2(m, source)).map((m) => this.mastraMessageV2ToMastraMessageV3(m)).map((m) => _MessageList.mastraMessageV3ToAIV5UIMessage(m))
    );
  }
  aiV5UIMessageToMastraMessageV3(message, messageSource) {
    const content = {
      format: 3,
      parts: message.parts,
      metadata: message.metadata
    };
    const metadata = message.metadata;
    const createdAt = (() => {
      if ("createdAt" in message && message.createdAt instanceof Date) {
        return message.createdAt;
      }
      if (metadata && "createdAt" in metadata && metadata.createdAt instanceof Date) {
        return metadata.createdAt;
      }
      return void 0;
    })();
    if ("metadata" in message && message.metadata) {
      content.metadata = { ...message.metadata };
    }
    return {
      id: message.id || this.newMessageId(),
      role: _MessageList.getRole(message),
      createdAt: this.generateCreatedAt(messageSource, createdAt),
      threadId: this.memoryInfo?.threadId,
      resourceId: this.memoryInfo?.resourceId,
      content
    };
  }
  aiV5ModelMessageToMastraMessageV3(coreMessage, messageSource) {
    const id = `id` in coreMessage && typeof coreMessage.id === `string` ? coreMessage.id : this.newMessageId();
    const parts = [];
    if (typeof coreMessage.content === "string") {
      parts.push({
        type: "text",
        text: coreMessage.content
      });
    } else if (Array.isArray(coreMessage.content)) {
      for (const part of coreMessage.content) {
        switch (part.type) {
          case "text":
            const prevPart = parts.at(-1);
            if (coreMessage.role === "assistant" && prevPart && AIV5__namespace.isToolUIPart(prevPart) && prevPart.state === "output-available") {
              parts.push({
                type: "step-start"
              });
            }
            parts.push({
              type: "text",
              text: part.text,
              providerMetadata: part.providerOptions
            });
            break;
          case "tool-call":
            parts.push({
              type: `tool-${part.toolName}`,
              state: "input-available",
              toolCallId: part.toolCallId,
              input: part.input
            });
            break;
          case "tool-result":
            parts.push({
              type: `tool-${part.toolName}`,
              state: "output-available",
              toolCallId: part.toolCallId,
              output: typeof part.output === "string" ? { type: "text", value: part.output } : part.output ?? { type: "text", value: "" },
              input: {},
              callProviderMetadata: part.providerOptions
            });
            break;
          case "reasoning":
            parts.push({
              type: "reasoning",
              text: part.text,
              providerMetadata: part.providerOptions
            });
            break;
          case "image":
            parts.push({
              type: "file",
              url: part.image.toString(),
              mediaType: part.mediaType || "unknown",
              providerMetadata: part.providerOptions
            });
            break;
          case "file":
            if (part.data instanceof URL) {
              parts.push({
                type: "file",
                url: part.data.toString(),
                mediaType: part.mediaType,
                providerMetadata: part.providerOptions
              });
            } else {
              try {
                parts.push({
                  type: "file",
                  mediaType: part.mediaType,
                  url: convertDataContentToBase64String(part.data),
                  providerMetadata: part.providerOptions
                });
              } catch (error) {
                console.error(`Failed to convert binary data to base64 in CoreMessage file part: ${error}`, error);
              }
            }
            break;
        }
      }
    }
    const content = {
      format: 3,
      parts
    };
    if (coreMessage.content) {
      content.metadata = {
        ...content.metadata || {},
        __originalContent: coreMessage.content
      };
    }
    return {
      id,
      role: _MessageList.getRole(coreMessage),
      createdAt: this.generateCreatedAt(messageSource),
      threadId: this.memoryInfo?.threadId,
      resourceId: this.memoryInfo?.resourceId,
      content
    };
  }
  static hasAIV5UIMessageCharacteristics(msg) {
    if (`toolInvocations` in msg || `reasoning` in msg || `experimental_attachments` in msg || `data` in msg || `annotations` in msg)
      return false;
    if (!msg.parts) return false;
    for (const part of msg.parts) {
      if (`metadata` in part) return true;
      if (`toolInvocation` in part) return false;
      if (`toolCallId` in part) return true;
      if (part.type === `source`) return false;
      if (part.type === `source-url`) return true;
      if (part.type === `reasoning`) {
        if (`state` in part || `text` in part) return true;
        if (`reasoning` in part || `details` in part) return false;
      }
      if (part.type === `file` && `mediaType` in part) return true;
    }
    return false;
  }
  static isAIV5UIMessage(msg) {
    return !_MessageList.isMastraMessage(msg) && !_MessageList.isAIV5CoreMessage(msg) && `parts` in msg && _MessageList.hasAIV5UIMessageCharacteristics(msg);
  }
  static hasAIV5CoreMessageCharacteristics(msg) {
    if (`experimental_providerMetadata` in msg) return false;
    if (typeof msg.content === `string`) return false;
    for (const part of msg.content) {
      if (part.type === `tool-result` && `output` in part) return true;
      if (part.type === `tool-call` && `input` in part) return true;
      if (part.type === `tool-result` && `result` in part) return false;
      if (part.type === `tool-call` && `args` in part) return false;
      if (`mediaType` in part) return true;
      if (`mimeType` in part) return false;
      if (`experimental_providerMetadata` in part) return false;
      if (part.type === `reasoning` && `signature` in part) return false;
      if (part.type === `redacted-reasoning`) return false;
    }
    return false;
  }
  static cacheKeyFromAIV5Parts(parts) {
    let key = ``;
    for (const part of parts) {
      key += part.type;
      if (part.type === `text`) {
        key += part.text;
      }
      if (AIV5__namespace.isToolUIPart(part) || part.type === "dynamic-tool") {
        key += part.toolCallId;
        key += part.state;
      }
      if (part.type === `reasoning`) {
        key += part.text;
      }
      if (part.type === `file`) {
        key += part.url.length;
        key += part.mediaType;
        key += part.filename || "";
      }
    }
    return key;
  }
  static cacheKeyFromAIV5ModelMessageContent(content) {
    if (typeof content === `string`) return content;
    let key = ``;
    for (const part of content) {
      key += part.type;
      if (part.type === `text`) {
        key += part.text.length;
      }
      if (part.type === `reasoning`) {
        key += part.text.length;
      }
      if (part.type === `tool-call`) {
        key += part.toolCallId;
        key += part.toolName;
      }
      if (part.type === `tool-result`) {
        key += part.toolCallId;
        key += part.toolName;
      }
      if (part.type === `file`) {
        key += part.filename;
        key += part.mediaType;
      }
      if (part.type === `image`) {
        key += part.image instanceof URL ? part.image.toString() : part.image.toString().length;
        key += part.mediaType;
      }
    }
    return key;
  }
};

// src/agent/message-list/utils/convert-messages.ts
var MessageConverter = class {
  messageList;
  constructor(messages) {
    this.messageList = new MessageList();
    this.messageList.add(messages, "memory");
  }
  to(format) {
    switch (format) {
      case "Mastra.V2":
        return this.messageList.get.all.v2();
      case "AIV4.UI":
        return this.messageList.get.all.aiV4.ui();
      case "AIV4.Core":
        return this.messageList.get.all.aiV4.core();
      case "AIV5.UI":
        return this.messageList.get.all.aiV5.ui();
      case "AIV5.Model":
        return this.messageList.get.all.aiV5.model();
      default:
        throw new Error(`Unsupported output format: ${format}`);
    }
  }
};
function convertMessages(messages) {
  return new MessageConverter(messages);
}

exports.DefaultGeneratedFile = DefaultGeneratedFile;
exports.DefaultGeneratedFileWithType = DefaultGeneratedFileWithType;
exports.MessageList = MessageList;
exports.convertMessages = convertMessages;
//# sourceMappingURL=chunk-QA2TWVUS.cjs.map
//# sourceMappingURL=chunk-QA2TWVUS.cjs.map