import { MastraStorage } from '../chunk-YGW2WEJ5.js';
export { MastraStorage, ensureDate, resolveMessageLimit, serializeDate } from '../chunk-YGW2WEJ5.js';
import { TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS, TABLE_TRACES } from '../chunk-R5GESRGB.js';
export { AI_SPAN_SCHEMA, SCORERS_SCHEMA, TABLE_AI_SPANS, TABLE_EVALS, TABLE_MESSAGES, TABLE_RESOURCES, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_THREADS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT } from '../chunk-R5GESRGB.js';
import { MessageList } from '../chunk-C5C4PN54.js';
import { MastraError } from '../chunk-MCOVMKIS.js';
import { MastraBase } from '../chunk-6GF5M4GX.js';

// src/storage/domains/legacy-evals/base.ts
var LegacyEvalsStorage = class extends MastraBase {
  constructor() {
    super({
      component: "STORAGE",
      name: "LEGACY_EVALS"
    });
  }
};

// src/storage/domains/legacy-evals/inmemory.ts
var InMemoryLegacyEvals = class extends LegacyEvalsStorage {
  collection;
  constructor({ collection }) {
    super();
    this.collection = collection;
  }
  async getEvals(options) {
    this.logger.debug(`MockStore: getEvals called`, options);
    let evals = Array.from(this.collection.values());
    if (options.agentName) {
      evals = evals.filter((evalR) => evalR.agent_name === options.agentName);
    }
    if (options.type === "test") {
      evals = evals.filter((evalR) => evalR.test_info && evalR.test_info.testPath);
    } else if (options.type === "live") {
      evals = evals.filter((evalR) => !evalR.test_info || !evalR.test_info.testPath);
    }
    if (options.dateRange?.start) {
      evals = evals.filter((evalR) => new Date(evalR.created_at) >= options.dateRange.start);
    }
    if (options.dateRange?.end) {
      evals = evals.filter((evalR) => new Date(evalR.created_at) <= options.dateRange.end);
    }
    evals.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
    const total = evals.length;
    const page = options.page || 0;
    const perPage = options.perPage || 100;
    const start = page * perPage;
    const end = start + perPage;
    return {
      evals: evals.slice(start, end).map((e) => ({
        agentName: e.agent_name,
        input: e.input,
        output: e.output,
        instructions: e.instructions,
        result: e.result,
        createdAt: e.created_at.toISOString(),
        testInfo: e.test_info,
        metricName: e.metric_name,
        runId: e.run_id,
        globalRunId: e.global_run_id
      })),
      total,
      page,
      perPage,
      hasMore: total > end
    };
  }
  async getEvalsByAgentName(agentName, type) {
    this.logger.debug(`MockStore: getEvalsByAgentName called for ${agentName}`);
    let evals = Array.from(this.collection.values()).filter((e) => e.agent_name === agentName);
    if (type === "test") {
      evals = evals.filter((e) => e.test_info && e.test_info.testPath);
    } else if (type === "live") {
      evals = evals.filter((e) => !e.test_info || !e.test_info.testPath);
    }
    return evals.sort(
      (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
    ).map((e) => ({
      agentName: e.agent_name,
      input: e.input,
      output: e.output,
      instructions: e.instructions,
      result: e.result,
      createdAt: e.created_at.toISOString(),
      metricName: e.metric_name,
      runId: e.run_id,
      testInfo: e.test_info,
      globalRunId: e.global_run_id
    }));
  }
};

// src/storage/domains/memory/base.ts
var MemoryStorage = class extends MastraBase {
  constructor() {
    super({
      component: "STORAGE",
      name: "MEMORY"
    });
  }
  async deleteMessages(_messageIds) {
    throw new Error(
      `Message deletion is not supported by this storage adapter (${this.constructor.name}). The deleteMessages method needs to be implemented in the storage adapter.`
    );
  }
  async getResourceById(_) {
    throw new Error(
      `Resource working memory is not supported by this storage adapter (${this.constructor.name}). Supported storage adapters: LibSQL (@mastra/libsql), PostgreSQL (@mastra/pg), Upstash (@mastra/upstash). To use per-resource working memory, switch to one of these supported storage adapters.`
    );
  }
  async saveResource(_) {
    throw new Error(
      `Resource working memory is not supported by this storage adapter (${this.constructor.name}). Supported storage adapters: LibSQL (@mastra/libsql), PostgreSQL (@mastra/pg), Upstash (@mastra/upstash). To use per-resource working memory, switch to one of these supported storage adapters.`
    );
  }
  async updateResource(_) {
    throw new Error(
      `Resource working memory is not supported by this storage adapter (${this.constructor.name}). Supported storage adapters: LibSQL (@mastra/libsql), PostgreSQL (@mastra/pg), Upstash (@mastra/upstash). To use per-resource working memory, switch to one of these supported storage adapters.`
    );
  }
  castThreadOrderBy(v) {
    return v in THREAD_ORDER_BY_SET ? v : "createdAt";
  }
  castThreadSortDirection(v) {
    return v in THREAD_THREAD_SORT_DIRECTION_SET ? v : "DESC";
  }
};
var THREAD_ORDER_BY_SET = {
  createdAt: true,
  updatedAt: true
};
var THREAD_THREAD_SORT_DIRECTION_SET = {
  ASC: true,
  DESC: true
};

// src/storage/domains/memory/inmemory.ts
var InMemoryMemory = class extends MemoryStorage {
  collection;
  operations;
  constructor({
    collection,
    operations
  }) {
    super();
    this.collection = collection;
    this.operations = operations;
  }
  async getThreadById({ threadId }) {
    this.logger.debug(`MockStore: getThreadById called for ${threadId}`);
    const thread = this.collection.threads.get(threadId);
    return thread ? { ...thread, metadata: thread.metadata ? { ...thread.metadata } : thread.metadata } : null;
  }
  async getThreadsByResourceId({
    resourceId,
    orderBy,
    sortDirection
  }) {
    this.logger.debug(`MockStore: getThreadsByResourceId called for ${resourceId}`);
    const threads = Array.from(this.collection.threads.values()).filter((t) => t.resourceId === resourceId);
    const sortedThreads = this.sortThreads(
      threads,
      this.castThreadOrderBy(orderBy),
      this.castThreadSortDirection(sortDirection)
    );
    return sortedThreads.map((thread) => ({
      ...thread,
      metadata: thread.metadata ? { ...thread.metadata } : thread.metadata
    }));
  }
  async saveThread({ thread }) {
    this.logger.debug(`MockStore: saveThread called for ${thread.id}`);
    const key = thread.id;
    this.collection.threads.set(key, thread);
    return thread;
  }
  async updateThread({
    id,
    title,
    metadata
  }) {
    this.logger.debug(`MockStore: updateThread called for ${id}`);
    const thread = this.collection.threads.get(id);
    if (!thread) {
      throw new Error(`Thread with id ${id} not found`);
    }
    if (thread) {
      thread.title = title;
      thread.metadata = { ...thread.metadata, ...metadata };
      thread.updatedAt = /* @__PURE__ */ new Date();
    }
    return thread;
  }
  async deleteThread({ threadId }) {
    this.logger.debug(`MockStore: deleteThread called for ${threadId}`);
    this.collection.threads.delete(threadId);
    this.collection.messages.forEach((msg, key) => {
      if (msg.thread_id === threadId) {
        this.collection.messages.delete(key);
      }
    });
  }
  async getMessages({ threadId, selectBy }) {
    this.logger.debug(`MockStore: getMessages called for thread ${threadId}`);
    const messages = [];
    if (selectBy?.include && selectBy.include.length > 0) {
      for (const includeItem of selectBy.include) {
        const targetMessage = this.collection.messages.get(includeItem.id);
        if (targetMessage) {
          const convertedMessage = {
            id: targetMessage.id,
            threadId: targetMessage.thread_id,
            content: typeof targetMessage.content === "string" ? JSON.parse(targetMessage.content) : targetMessage.content,
            role: targetMessage.role,
            type: targetMessage.type,
            createdAt: targetMessage.createdAt,
            resourceId: targetMessage.resourceId
          };
          messages.push(convertedMessage);
          if (includeItem.withPreviousMessages) {
            const allThreadMessages = Array.from(this.collection.messages.values()).filter((msg) => msg.thread_id === includeItem.threadId).sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
            const targetIndex = allThreadMessages.findIndex((msg) => msg.id === includeItem.id);
            if (targetIndex !== -1) {
              const startIndex = Math.max(0, targetIndex - (includeItem.withPreviousMessages || 0));
              for (let i = startIndex; i < targetIndex; i++) {
                const message = allThreadMessages[i];
                if (message && !messages.some((m) => m.id === message.id)) {
                  const convertedPrevMessage = {
                    id: message.id,
                    threadId: message.thread_id,
                    content: typeof message.content === "string" ? JSON.parse(message.content) : message.content,
                    role: message.role,
                    type: message.type,
                    createdAt: message.createdAt,
                    resourceId: message.resourceId
                  };
                  messages.push(convertedPrevMessage);
                }
              }
            }
          }
          if (includeItem.withNextMessages) {
            const allThreadMessages = Array.from(this.collection.messages.values()).filter((msg) => msg.thread_id === includeItem.threadId).sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
            const targetIndex = allThreadMessages.findIndex((msg) => msg.id === includeItem.id);
            if (targetIndex !== -1) {
              const endIndex = Math.min(
                allThreadMessages.length,
                targetIndex + (includeItem.withNextMessages || 0) + 1
              );
              for (let i = targetIndex + 1; i < endIndex; i++) {
                const message = allThreadMessages[i];
                if (message && !messages.some((m) => m.id === message.id)) {
                  const convertedNextMessage = {
                    id: message.id,
                    threadId: message.thread_id,
                    content: typeof message.content === "string" ? JSON.parse(message.content) : message.content,
                    role: message.role,
                    type: message.type,
                    createdAt: message.createdAt,
                    resourceId: message.resourceId
                  };
                  messages.push(convertedNextMessage);
                }
              }
            }
          }
        }
      }
    }
    if (!selectBy?.include || selectBy.include.length === 0 || selectBy?.last) {
      let threadMessages = Array.from(this.collection.messages.values()).filter((msg) => msg.thread_id === threadId).filter((msg) => !messages.some((m) => m.id === msg.id));
      if (selectBy?.last) {
        threadMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
        const lastMessages = threadMessages.slice(-selectBy.last);
        for (const msg of lastMessages) {
          const convertedMessage = {
            id: msg.id,
            threadId: msg.thread_id,
            content: typeof msg.content === "string" ? JSON.parse(msg.content) : msg.content,
            role: msg.role,
            type: msg.type,
            createdAt: msg.createdAt,
            resourceId: msg.resourceId
          };
          messages.push(convertedMessage);
        }
      } else if (!selectBy?.include || selectBy.include.length === 0) {
        for (const msg of threadMessages) {
          const convertedMessage = this.parseStoredMessage(msg);
          messages.push(convertedMessage);
        }
      }
    }
    messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
    return messages;
  }
  parseStoredMessage(message) {
    const { resourceId, content, role, thread_id, ...rest } = message;
    return {
      ...rest,
      threadId: thread_id,
      ...message.resourceId && { resourceId: message.resourceId },
      content: typeof content === "string" ? content : JSON.parse(content),
      role
    };
  }
  async getMessagesById({
    messageIds,
    format
  }) {
    this.logger.debug(`MockStore: getMessagesById called`);
    const rawMessages = messageIds.map((id) => this.collection.messages.get(id)).filter((message) => !!message);
    const list = new MessageList().add(rawMessages.map(this.parseStoredMessage), "memory");
    if (format === "v1") return list.get.all.v1();
    return list.get.all.v2();
  }
  async saveMessages(args) {
    const { messages, format = "v1" } = args;
    this.logger.debug(`MockStore: saveMessages called with ${messages.length} messages`);
    if (messages.some((msg) => msg.id === "error-message" || msg.resourceId === null)) {
      throw new Error("Simulated error for testing");
    }
    const threadIds = new Set(messages.map((msg) => msg.threadId).filter((id) => Boolean(id)));
    for (const threadId of threadIds) {
      const thread = this.collection.threads.get(threadId);
      if (thread) {
        thread.updatedAt = /* @__PURE__ */ new Date();
      }
    }
    for (const message of messages) {
      const key = message.id;
      const storageMessage = {
        id: message.id,
        thread_id: message.threadId || "",
        content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
        role: message.role || "user",
        type: message.type || "text",
        createdAt: message.createdAt,
        resourceId: message.resourceId || null
      };
      this.collection.messages.set(key, storageMessage);
    }
    const list = new MessageList().add(messages, "memory");
    if (format === `v2`) return list.get.all.v2();
    return list.get.all.v1();
  }
  async updateMessages(args) {
    const updatedMessages = [];
    for (const update of args.messages) {
      const storageMsg = this.collection.messages.get(update.id);
      if (!storageMsg) continue;
      const oldThreadId = storageMsg.thread_id;
      const newThreadId = update.threadId || oldThreadId;
      let threadIdChanged = false;
      if (update.threadId && update.threadId !== oldThreadId) {
        threadIdChanged = true;
      }
      if (update.role !== void 0) storageMsg.role = update.role;
      if (update.type !== void 0) storageMsg.type = update.type;
      if (update.createdAt !== void 0) storageMsg.createdAt = update.createdAt;
      if (update.resourceId !== void 0) storageMsg.resourceId = update.resourceId;
      if (update.content !== void 0) {
        let oldContent = typeof storageMsg.content === "string" ? JSON.parse(storageMsg.content) : storageMsg.content;
        let newContent = update.content;
        if (typeof newContent === "object" && typeof oldContent === "object") {
          newContent = { ...oldContent, ...newContent };
          if (oldContent.metadata && newContent.metadata) {
            newContent.metadata = { ...oldContent.metadata, ...newContent.metadata };
          }
        }
        storageMsg.content = JSON.stringify(newContent);
      }
      if (threadIdChanged) {
        storageMsg.thread_id = newThreadId;
        const base = Date.now();
        let oldThreadNewTime;
        const oldThread = this.collection.threads.get(oldThreadId);
        if (oldThread) {
          const prev = new Date(oldThread.updatedAt).getTime();
          oldThreadNewTime = Math.max(base, prev + 1);
          oldThread.updatedAt = new Date(oldThreadNewTime);
        }
        const newThread = this.collection.threads.get(newThreadId);
        if (newThread) {
          const prev = new Date(newThread.updatedAt).getTime();
          let newThreadNewTime = Math.max(base + 1, prev + 1);
          if (oldThreadNewTime !== void 0 && newThreadNewTime <= oldThreadNewTime) {
            newThreadNewTime = oldThreadNewTime + 1;
          }
          newThread.updatedAt = new Date(newThreadNewTime);
        }
      } else {
        const thread = this.collection.threads.get(oldThreadId);
        if (thread) {
          const prev = new Date(thread.updatedAt).getTime();
          let newTime = Date.now();
          if (newTime <= prev) newTime = prev + 1;
          thread.updatedAt = new Date(newTime);
        }
      }
      this.collection.messages.set(update.id, storageMsg);
      updatedMessages.push({
        id: storageMsg.id,
        threadId: storageMsg.thread_id,
        content: typeof storageMsg.content === "string" ? JSON.parse(storageMsg.content) : storageMsg.content,
        role: storageMsg.role === "user" || storageMsg.role === "assistant" ? storageMsg.role : "user",
        type: storageMsg.type,
        createdAt: storageMsg.createdAt,
        resourceId: storageMsg.resourceId === null ? void 0 : storageMsg.resourceId
      });
    }
    return updatedMessages;
  }
  async deleteMessages(messageIds) {
    if (!messageIds || messageIds.length === 0) {
      return;
    }
    this.logger.debug(`MockStore: deleteMessages called for ${messageIds.length} messages`);
    const threadIds = /* @__PURE__ */ new Set();
    for (const messageId of messageIds) {
      const message = this.collection.messages.get(messageId);
      if (message && message.thread_id) {
        threadIds.add(message.thread_id);
      }
      this.collection.messages.delete(messageId);
    }
    const now = /* @__PURE__ */ new Date();
    for (const threadId of threadIds) {
      const thread = this.collection.threads.get(threadId);
      if (thread) {
        thread.updatedAt = now;
      }
    }
  }
  async getThreadsByResourceIdPaginated(args) {
    const { resourceId, page, perPage, orderBy, sortDirection } = args;
    this.logger.debug(`MockStore: getThreadsByResourceIdPaginated called for ${resourceId}`);
    const threads = Array.from(this.collection.threads.values()).filter((t) => t.resourceId === resourceId);
    const sortedThreads = this.sortThreads(
      threads,
      this.castThreadOrderBy(orderBy),
      this.castThreadSortDirection(sortDirection)
    );
    const clonedThreads = sortedThreads.map((thread) => ({
      ...thread,
      metadata: thread.metadata ? { ...thread.metadata } : thread.metadata
    }));
    return {
      threads: clonedThreads.slice(page * perPage, (page + 1) * perPage),
      total: clonedThreads.length,
      page,
      perPage,
      hasMore: clonedThreads.length > (page + 1) * perPage
    };
  }
  async getMessagesPaginated({
    threadId,
    selectBy
  }) {
    this.logger.debug(`MockStore: getMessagesPaginated called for thread ${threadId}`);
    const { page = 0, perPage = 40 } = selectBy?.pagination || {};
    const messages = [];
    if (selectBy?.include && selectBy.include.length > 0) {
      for (const includeItem of selectBy.include) {
        const targetMessage = this.collection.messages.get(includeItem.id);
        if (targetMessage) {
          const convertedMessage = {
            id: targetMessage.id,
            threadId: targetMessage.thread_id,
            content: typeof targetMessage.content === "string" ? JSON.parse(targetMessage.content) : targetMessage.content,
            role: targetMessage.role,
            type: targetMessage.type,
            createdAt: targetMessage.createdAt,
            resourceId: targetMessage.resourceId
          };
          messages.push(convertedMessage);
          if (includeItem.withPreviousMessages) {
            const allThreadMessages = Array.from(this.collection.messages.values()).filter((msg) => msg.thread_id === includeItem.threadId).sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
            const targetIndex = allThreadMessages.findIndex((msg) => msg.id === includeItem.id);
            if (targetIndex !== -1) {
              const startIndex = Math.max(0, targetIndex - (includeItem.withPreviousMessages || 0));
              for (let i = startIndex; i < targetIndex; i++) {
                const message = allThreadMessages[i];
                if (message && !messages.some((m) => m.id === message.id)) {
                  const convertedPrevMessage = {
                    id: message.id,
                    threadId: message.thread_id,
                    content: typeof message.content === "string" ? JSON.parse(message.content) : message.content,
                    role: message.role,
                    type: message.type,
                    createdAt: message.createdAt,
                    resourceId: message.resourceId
                  };
                  messages.push(convertedPrevMessage);
                }
              }
            }
          }
          if (includeItem.withNextMessages) {
            const allThreadMessages = Array.from(this.collection.messages.values()).filter((msg) => msg.thread_id === includeItem.threadId).sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
            const targetIndex = allThreadMessages.findIndex((msg) => msg.id === includeItem.id);
            if (targetIndex !== -1) {
              const endIndex = Math.min(
                allThreadMessages.length,
                targetIndex + (includeItem.withNextMessages || 0) + 1
              );
              for (let i = targetIndex + 1; i < endIndex; i++) {
                const message = allThreadMessages[i];
                if (message && !messages.some((m) => m.id === message.id)) {
                  const convertedNextMessage = {
                    id: message.id,
                    threadId: message.thread_id,
                    content: typeof message.content === "string" ? JSON.parse(message.content) : message.content,
                    role: message.role,
                    type: message.type,
                    createdAt: message.createdAt,
                    resourceId: message.resourceId
                  };
                  messages.push(convertedNextMessage);
                }
              }
            }
          }
        }
      }
    }
    if (!selectBy?.include || selectBy.include.length === 0 || selectBy?.last) {
      let threadMessages = Array.from(this.collection.messages.values()).filter((msg) => msg.thread_id === threadId).filter((msg) => !messages.some((m) => m.id === msg.id));
      if (selectBy?.pagination?.dateRange) {
        const { start: from, end: to } = selectBy.pagination.dateRange;
        threadMessages = threadMessages.filter((msg) => {
          const msgDate = new Date(msg.createdAt);
          const fromDate = from ? new Date(from) : null;
          const toDate = to ? new Date(to) : null;
          if (fromDate && msgDate < fromDate) return false;
          if (toDate && msgDate > toDate) return false;
          return true;
        });
      }
      if (selectBy?.last) {
        threadMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
        const lastMessages = threadMessages.slice(-selectBy.last);
        for (const msg of lastMessages) {
          const convertedMessage = {
            id: msg.id,
            threadId: msg.thread_id,
            content: typeof msg.content === "string" ? JSON.parse(msg.content) : msg.content,
            role: msg.role,
            type: msg.type,
            createdAt: msg.createdAt,
            resourceId: msg.resourceId
          };
          messages.push(convertedMessage);
        }
      } else if (!selectBy?.include || selectBy.include.length === 0) {
        for (const msg of threadMessages) {
          const convertedMessage = {
            id: msg.id,
            threadId: msg.thread_id,
            content: typeof msg.content === "string" ? JSON.parse(msg.content) : msg.content,
            role: msg.role,
            type: msg.type,
            createdAt: msg.createdAt,
            resourceId: msg.resourceId
          };
          messages.push(convertedMessage);
        }
      }
    }
    messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
    const start = page * perPage;
    const end = start + perPage;
    return {
      messages: messages.slice(start, end),
      total: messages.length,
      page,
      perPage,
      hasMore: messages.length > end
    };
  }
  async getResourceById({ resourceId }) {
    this.logger.debug(`MockStore: getResourceById called for ${resourceId}`);
    const resource = this.collection.resources.get(resourceId);
    return resource ? { ...resource, metadata: resource.metadata ? { ...resource.metadata } : resource.metadata } : null;
  }
  async saveResource({ resource }) {
    this.logger.debug(`MockStore: saveResource called for ${resource.id}`);
    this.collection.resources.set(resource.id, resource);
    return resource;
  }
  async updateResource({
    resourceId,
    workingMemory,
    metadata
  }) {
    this.logger.debug(`MockStore: updateResource called for ${resourceId}`);
    let resource = this.collection.resources.get(resourceId);
    if (!resource) {
      resource = {
        id: resourceId,
        workingMemory,
        metadata: metadata || {},
        createdAt: /* @__PURE__ */ new Date(),
        updatedAt: /* @__PURE__ */ new Date()
      };
    } else {
      resource = {
        ...resource,
        workingMemory: workingMemory !== void 0 ? workingMemory : resource.workingMemory,
        metadata: {
          ...resource.metadata,
          ...metadata
        },
        updatedAt: /* @__PURE__ */ new Date()
      };
    }
    this.collection.resources.set(resourceId, resource);
    return resource;
  }
  sortThreads(threads, orderBy, sortDirection) {
    return threads.sort((a, b) => {
      const aValue = new Date(a[orderBy]).getTime();
      const bValue = new Date(b[orderBy]).getTime();
      if (sortDirection === "ASC") {
        return aValue - bValue;
      } else {
        return bValue - aValue;
      }
    });
  }
};

// src/storage/domains/observability/base.ts
var ObservabilityStorage = class extends MastraBase {
  constructor() {
    super({
      component: "STORAGE",
      name: "OBSERVABILITY"
    });
  }
  /**
   * Provides hints for AI tracing strategy selection by the DefaultExporter.
   * Storage adapters can override this to specify their preferred and supported strategies.
   */
  get aiTracingStrategy() {
    return {
      preferred: "batch-with-updates",
      // Default for most SQL stores
      supported: ["realtime", "batch-with-updates", "insert-only"]
    };
  }
  /**
   * Creates a single AI span record in the storage provider.
   */
  createAISpan(_span) {
    throw new MastraError({
      id: "OBSERVABILITY_CREATE_AI_SPAN_NOT_IMPLEMENTED",
      domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
      category: "SYSTEM" /* SYSTEM */,
      text: "This storage provider does not support creating AI spans"
    });
  }
  /**
   * Updates a single AI span with partial data. Primarily used for realtime trace creation.
   */
  updateAISpan(_params) {
    throw new MastraError({
      id: "OBSERVABILITY_STORAGE_UPDATE_AI_SPAN_NOT_IMPLEMENTED",
      domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
      category: "SYSTEM" /* SYSTEM */,
      text: "This storage provider does not support updating AI spans"
    });
  }
  /**
   * Retrieves a single AI trace with all its associated spans.
   */
  getAITrace(_traceId) {
    throw new MastraError({
      id: "OBSERVABILITY_STORAGE_GET_AI_TRACE_NOT_IMPLEMENTED",
      domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
      category: "SYSTEM" /* SYSTEM */,
      text: "This storage provider does not support getting AI traces"
    });
  }
  /**
   * Retrieves a paginated list of AI traces with optional filtering.
   */
  getAITracesPaginated(_args) {
    throw new MastraError({
      id: "OBSERVABILITY_STORAGE_GET_AI_TRACES_PAGINATED_NOT_IMPLEMENTED",
      domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
      category: "SYSTEM" /* SYSTEM */,
      text: "This storage provider does not support getting AI traces paginated"
    });
  }
  /**
   * Creates multiple AI spans in a single batch.
   */
  batchCreateAISpans(_args) {
    throw new MastraError({
      id: "OBSERVABILITY_STORAGE_BATCH_CREATE_AI_SPAN_NOT_IMPLEMENTED",
      domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
      category: "SYSTEM" /* SYSTEM */,
      text: "This storage provider does not support batch creating AI spans"
    });
  }
  /**
   * Updates multiple AI spans in a single batch.
   */
  batchUpdateAISpans(_args) {
    throw new MastraError({
      id: "OBSERVABILITY_STORAGE_BATCH_UPDATE_AI_SPAN_NOT_IMPLEMENTED",
      domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
      category: "SYSTEM" /* SYSTEM */,
      text: "This storage provider does not support batch updating AI spans"
    });
  }
  /**
   * Deletes multiple AI traces and all their associated spans in a single batch operation.
   */
  batchDeleteAITraces(_args) {
    throw new MastraError({
      id: "OBSERVABILITY_STORAGE_BATCH_DELETE_AI_SPAN_NOT_IMPLEMENTED",
      domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
      category: "SYSTEM" /* SYSTEM */,
      text: "This storage provider does not support batch deleting AI traces"
    });
  }
};

// src/storage/domains/observability/inmemory.ts
var ObservabilityInMemory = class extends ObservabilityStorage {
  operations;
  collection;
  constructor({ collection, operations }) {
    super();
    this.collection = collection;
    this.operations = operations;
  }
  get aiTracingStrategy() {
    return {
      preferred: "realtime",
      supported: ["realtime", "batch-with-updates", "insert-only"]
    };
  }
  async createAISpan(span) {
    this.validateCreateAISpan(span);
    const id = this.generateId(span);
    this.collection.set(id, span);
  }
  validateCreateAISpan(record) {
    if (!record.spanId) {
      throw new MastraError({
        id: "OBSERVABILITY_SPAN_ID_REQUIRED",
        domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
        category: "SYSTEM" /* SYSTEM */,
        text: "Span ID is required for creating a span"
      });
    }
    if (!record.traceId) {
      throw new MastraError({
        id: "OBSERVABILITY_TRACE_ID_REQUIRED",
        domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
        category: "SYSTEM" /* SYSTEM */,
        text: "Trace ID is required for creating a span"
      });
    }
  }
  generateId({ traceId, spanId }) {
    return `${traceId}-${spanId}`;
  }
  async getAITrace(traceId) {
    const spans = Array.from(this.collection.values()).filter((span) => span.traceId === traceId);
    if (spans.length === 0) {
      return null;
    }
    spans.sort((a, b) => a.startedAt.getTime() - b.startedAt.getTime());
    return {
      traceId,
      spans
    };
  }
  async getAITracesPaginated({
    filters,
    pagination
  }) {
    const allRootSpans = this.filterForRootSpans(Array.from(this.collection.values()));
    const filteredRootSpans = this.filterSpansByFilter(allRootSpans, filters);
    const startDate = pagination?.dateRange?.start;
    const endDate = pagination?.dateRange?.end;
    const filteredRootSpansByDate = this.filterSpansByDate(filteredRootSpans, startDate, endDate);
    const total = filteredRootSpansByDate.length;
    const page = pagination?.page ?? 0;
    const perPage = pagination?.perPage ?? 10;
    const start = page * perPage;
    const end = start + perPage;
    const paged = this.filterSpansByPagination(filteredRootSpansByDate, pagination);
    return {
      spans: paged,
      pagination: { total, page, perPage, hasMore: end < total }
    };
  }
  filterForRootSpans(spans) {
    return spans.filter((span) => span.parentSpanId === null);
  }
  filterSpansByDate(spans, startDate, endDate) {
    return spans.filter((span) => {
      if (startDate && span.startedAt < startDate) return false;
      if (endDate && span.startedAt > endDate) return false;
      return true;
    });
  }
  filterSpansByFilter(spans, filter) {
    return spans.filter((span) => {
      if (filter?.name && span.name !== filter.name) return false;
      if (filter?.spanType && span.spanType !== filter.spanType) return false;
      return true;
    });
  }
  filterSpansByPagination(spans, pagination) {
    const page = pagination?.page ?? 0;
    const perPage = pagination?.perPage ?? 10;
    const start = page * perPage;
    const end = start + perPage;
    return spans.slice(start, end);
  }
  async updateAISpan(params) {
    const id = this.generateId({ traceId: params.traceId, spanId: params.spanId });
    const span = this.collection.get(id);
    if (!span) {
      throw new MastraError({
        id: "OBSERVABILITY_UPDATE_AI_SPAN_NOT_FOUND",
        domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
        category: "SYSTEM" /* SYSTEM */,
        text: "Span not found for update"
      });
    }
    this.collection.set(id, { ...span, ...params.updates });
  }
  async batchCreateAISpans(args) {
    for (const record of args.records) {
      this.validateCreateAISpan(record);
      const id = this.generateId({ traceId: record.traceId, spanId: record.spanId });
      this.collection.set(id, record);
    }
  }
  async batchUpdateAISpans(args) {
    for (const record of args.records) {
      const id = this.generateId({ traceId: record.traceId, spanId: record.spanId });
      const span = this.collection.get(id);
      if (!span) {
        throw new MastraError({
          id: "OBSERVABILITY_BATCH_UPDATE_AI_SPAN_NOT_FOUND",
          domain: "MASTRA_OBSERVABILITY" /* MASTRA_OBSERVABILITY */,
          category: "SYSTEM" /* SYSTEM */,
          text: "Span not found for batch update"
        });
      }
      this.collection.set(id, { ...span, ...record.updates });
    }
  }
  async batchDeleteAITraces(args) {
    for (const traceId of args.traceIds) {
      const spans = Array.from(this.collection.values()).filter((span) => span.traceId === traceId);
      for (const span of spans) {
        this.collection.delete(this.generateId({ traceId: span.traceId, spanId: span.spanId }));
      }
    }
  }
};

// src/storage/domains/operations/base.ts
var StoreOperations = class extends MastraBase {
  constructor() {
    super({
      component: "STORAGE",
      name: "OPERATIONS"
    });
  }
  getSqlType(type) {
    switch (type) {
      case "text":
        return "TEXT";
      case "timestamp":
        return "TIMESTAMP";
      case "float":
        return "FLOAT";
      case "integer":
        return "INTEGER";
      case "bigint":
        return "BIGINT";
      case "jsonb":
        return "JSONB";
      default:
        return "TEXT";
    }
  }
  getDefaultValue(type) {
    switch (type) {
      case "text":
      case "uuid":
        return "DEFAULT ''";
      case "timestamp":
        return "DEFAULT '1970-01-01 00:00:00'";
      case "integer":
      case "bigint":
      case "float":
        return "DEFAULT 0";
      case "jsonb":
        return "DEFAULT '{}'";
      default:
        return "DEFAULT ''";
    }
  }
};

// src/storage/domains/operations/inmemory.ts
var StoreOperationsInMemory = class extends StoreOperations {
  data;
  constructor() {
    super();
    this.data = {
      mastra_workflow_snapshot: /* @__PURE__ */ new Map(),
      mastra_evals: /* @__PURE__ */ new Map(),
      mastra_messages: /* @__PURE__ */ new Map(),
      mastra_threads: /* @__PURE__ */ new Map(),
      mastra_traces: /* @__PURE__ */ new Map(),
      mastra_resources: /* @__PURE__ */ new Map(),
      mastra_scorers: /* @__PURE__ */ new Map(),
      mastra_ai_spans: /* @__PURE__ */ new Map()
    };
  }
  getDatabase() {
    return this.data;
  }
  async insert({ tableName, record }) {
    const table = this.data[tableName];
    let key = record.id;
    if ([TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS].includes(tableName) && !record.id && record.run_id) {
      key = record.run_id;
      record.id = key;
    } else if (!record.id) {
      key = `auto-${Date.now()}-${Math.random()}`;
      record.id = key;
    }
    table.set(key, record);
  }
  async batchInsert({ tableName, records }) {
    const table = this.data[tableName];
    for (const record of records) {
      let key = record.id;
      if ([TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS].includes(tableName) && !record.id && record.run_id) {
        key = record.run_id;
        record.id = key;
      } else if (!record.id) {
        key = `auto-${Date.now()}-${Math.random()}`;
        record.id = key;
      }
      table.set(key, record);
    }
  }
  async load({ tableName, keys }) {
    this.logger.debug(`MockStore: load called for ${tableName} with keys`, keys);
    const table = this.data[tableName];
    const records = Array.from(table.values());
    return records.filter((record) => Object.keys(keys).every((key) => record[key] === keys[key]))?.[0];
  }
  async createTable({
    tableName,
    schema
  }) {
    this.logger.debug(`MockStore: createTable called for ${tableName} with schema`, schema);
    this.data[tableName] = /* @__PURE__ */ new Map();
  }
  async clearTable({ tableName }) {
    this.logger.debug(`MockStore: clearTable called for ${tableName}`);
    this.data[tableName].clear();
  }
  async dropTable({ tableName }) {
    this.logger.debug(`MockStore: dropTable called for ${tableName}`);
    this.data[tableName].clear();
  }
  async alterTable({
    tableName,
    schema
  }) {
    this.logger.debug(`MockStore: alterTable called for ${tableName} with schema`, schema);
  }
  async hasColumn(table, column) {
    this.logger.debug(`MockStore: hasColumn called for ${table} with column ${column}`);
    return true;
  }
};

// src/storage/domains/scores/base.ts
var ScoresStorage = class extends MastraBase {
  constructor() {
    super({
      component: "STORAGE",
      name: "SCORES"
    });
  }
};

// src/storage/domains/scores/inmemory.ts
var ScoresInMemory = class extends ScoresStorage {
  scores;
  constructor({ collection }) {
    super();
    this.scores = collection;
  }
  async getScoreById({ id }) {
    return this.scores.get(id) ?? null;
  }
  async saveScore(score) {
    const newScore = { id: crypto.randomUUID(), createdAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date(), ...score };
    this.scores.set(newScore.id, newScore);
    return { score: newScore };
  }
  async getScoresByScorerId({
    scorerId,
    pagination,
    entityId,
    entityType,
    source
  }) {
    const scores = Array.from(this.scores.values()).filter((score) => {
      let baseFilter = score.scorerId === scorerId;
      if (entityId) {
        baseFilter = baseFilter && score.entityId === entityId;
      }
      if (entityType) {
        baseFilter = baseFilter && score.entityType === entityType;
      }
      if (source) {
        baseFilter = baseFilter && score.source === source;
      }
      return baseFilter;
    });
    return {
      scores: scores.slice(pagination.page * pagination.perPage, (pagination.page + 1) * pagination.perPage),
      pagination: {
        total: scores.length,
        page: pagination.page,
        perPage: pagination.perPage,
        hasMore: scores.length > (pagination.page + 1) * pagination.perPage
      }
    };
  }
  async getScoresByRunId({
    runId,
    pagination
  }) {
    const scores = Array.from(this.scores.values()).filter((score) => score.runId === runId);
    return {
      scores: scores.slice(pagination.page * pagination.perPage, (pagination.page + 1) * pagination.perPage),
      pagination: {
        total: scores.length,
        page: pagination.page,
        perPage: pagination.perPage,
        hasMore: scores.length > (pagination.page + 1) * pagination.perPage
      }
    };
  }
  async getScoresByEntityId({
    entityId,
    entityType,
    pagination
  }) {
    const scores = Array.from(this.scores.values()).filter((score) => {
      const baseFilter = score.entityId === entityId && score.entityType === entityType;
      return baseFilter;
    });
    return {
      scores: scores.slice(pagination.page * pagination.perPage, (pagination.page + 1) * pagination.perPage),
      pagination: {
        total: scores.length,
        page: pagination.page,
        perPage: pagination.perPage,
        hasMore: scores.length > (pagination.page + 1) * pagination.perPage
      }
    };
  }
};

// src/storage/domains/traces/base.ts
var TracesStorage = class extends MastraBase {
  constructor() {
    super({
      component: "STORAGE",
      name: "TRACES"
    });
  }
};

// src/storage/domains/traces/inmemory.ts
var TracesInMemory = class extends TracesStorage {
  traces;
  operations;
  collection;
  constructor({ collection, operations }) {
    super();
    this.collection = collection;
    this.traces = collection;
    this.operations = operations;
  }
  async getTraces({
    name,
    scope,
    page,
    perPage,
    attributes,
    filters,
    fromDate,
    toDate
  }) {
    this.logger.debug(`MockStore: getTraces called`);
    let traces = Array.from(this.collection.values());
    if (name) traces = traces.filter((t) => t.name?.startsWith(name));
    if (scope) traces = traces.filter((t) => t.scope === scope);
    if (attributes) {
      traces = traces.filter(
        (t) => Object.entries(attributes).every(([key, value]) => t.attributes?.[key] === value)
      );
    }
    if (filters) {
      traces = traces.filter((t) => Object.entries(filters).every(([key, value]) => t[key] === value));
    }
    if (fromDate) traces = traces.filter((t) => new Date(t.createdAt) >= fromDate);
    if (toDate) traces = traces.filter((t) => new Date(t.createdAt) <= toDate);
    traces.sort((a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime());
    const start = page * perPage;
    const end = start + perPage;
    return traces.slice(start, end);
  }
  async getTracesPaginated({
    name,
    scope,
    attributes,
    page = 0,
    perPage = 10,
    dateRange
  }) {
    this.logger.debug(`MockStore: getTracesPaginated called`);
    let traces = Array.from(this.collection.values());
    if (name) traces = traces.filter((t) => t.name?.startsWith(name));
    if (scope) traces = traces.filter((t) => t.scope === scope);
    if (attributes) {
      traces = traces.filter(
        (t) => Object.entries(attributes).every(([key, value]) => t.attributes?.[key] === value)
      );
    }
    if (dateRange?.start) traces = traces.filter((t) => new Date(t.createdAt) >= dateRange.start);
    if (dateRange?.end) traces = traces.filter((t) => new Date(t.createdAt) <= dateRange.end);
    traces.sort((a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime());
    const start = page * perPage;
    const end = start + perPage;
    return {
      traces: traces.slice(start, end),
      total: traces.length,
      page,
      perPage,
      hasMore: traces.length > end
    };
  }
  async batchTraceInsert({ records }) {
    this.logger.debug("Batch inserting traces", { count: records.length });
    await this.operations.batchInsert({
      tableName: TABLE_TRACES,
      records
    });
  }
};

// src/storage/domains/workflows/base.ts
var WorkflowsStorage = class extends MastraBase {
  constructor() {
    super({
      component: "STORAGE",
      name: "WORKFLOWS"
    });
  }
};

// src/storage/domains/workflows/inmemory.ts
var WorkflowsInMemory = class extends WorkflowsStorage {
  operations;
  collection;
  constructor({ collection, operations }) {
    super();
    this.collection = collection;
    this.operations = operations;
  }
  async updateWorkflowResults({
    workflowName,
    runId,
    stepId,
    result,
    runtimeContext
  }) {
    this.logger.debug(`MockStore: updateWorkflowResults called for ${workflowName} ${runId} ${stepId}`, result);
    const run = this.collection.get(runId);
    if (!run) {
      return {};
    }
    let snapshot;
    if (!run.snapshot) {
      snapshot = {
        context: {},
        activePaths: [],
        timestamp: Date.now(),
        suspendedPaths: {},
        serializedStepGraph: [],
        value: {},
        waitingPaths: {},
        status: "pending",
        runId: run.run_id
      };
      this.collection.set(runId, {
        ...run,
        snapshot
      });
    }
    snapshot = typeof run.snapshot === "string" ? JSON.parse(run.snapshot) : run.snapshot;
    if (!snapshot || !snapshot?.context) {
      throw new Error(`Snapshot not found for runId ${runId}`);
    }
    snapshot.context[stepId] = result;
    snapshot.runtimeContext = { ...snapshot.runtimeContext, ...runtimeContext };
    this.collection.set(runId, {
      ...run,
      snapshot
    });
    return JSON.parse(JSON.stringify(snapshot.context));
  }
  async updateWorkflowState({
    runId,
    opts
  }) {
    const run = this.collection.get(runId);
    if (!run) {
      return;
    }
    let snapshot;
    if (!run.snapshot) {
      snapshot = {
        context: {},
        activePaths: [],
        timestamp: Date.now(),
        suspendedPaths: {},
        serializedStepGraph: [],
        value: {},
        waitingPaths: {},
        status: "pending",
        runId: run.run_id
      };
      this.collection.set(runId, {
        ...run,
        snapshot
      });
    } else {
      snapshot = typeof run.snapshot === "string" ? JSON.parse(run.snapshot) : run.snapshot;
    }
    if (!snapshot || !snapshot?.context) {
      throw new Error(`Snapshot not found for runId ${runId}`);
    }
    snapshot = { ...snapshot, ...opts };
    this.collection.set(runId, {
      ...run,
      snapshot
    });
    return snapshot;
  }
  async persistWorkflowSnapshot({
    workflowName,
    runId,
    snapshot
  }) {
    const data = {
      workflow_name: workflowName,
      run_id: runId,
      snapshot,
      createdAt: /* @__PURE__ */ new Date(),
      updatedAt: /* @__PURE__ */ new Date()
    };
    await this.operations.insert({
      tableName: TABLE_WORKFLOW_SNAPSHOT,
      record: data
    });
  }
  async loadWorkflowSnapshot({
    workflowName,
    runId
  }) {
    this.logger.debug("Loading workflow snapshot", { workflowName, runId });
    const d = await this.operations.load({
      tableName: TABLE_WORKFLOW_SNAPSHOT,
      keys: { workflow_name: workflowName, run_id: runId }
    });
    return d ? JSON.parse(JSON.stringify(d.snapshot)) : null;
  }
  async getWorkflowRuns({
    workflowName,
    fromDate,
    toDate,
    limit,
    offset,
    resourceId
  } = {}) {
    let runs = Array.from(this.collection.values());
    if (workflowName) runs = runs.filter((run) => run.workflow_name === workflowName);
    if (fromDate && toDate) {
      runs = runs.filter(
        (run) => new Date(run.createdAt).getTime() >= fromDate.getTime() && new Date(run.createdAt).getTime() <= toDate.getTime()
      );
    } else if (fromDate) {
      runs = runs.filter((run) => new Date(run.createdAt).getTime() >= fromDate.getTime());
    } else if (toDate) {
      runs = runs.filter((run) => new Date(run.createdAt).getTime() <= toDate.getTime());
    }
    if (resourceId) runs = runs.filter((run) => run.resourceId === resourceId);
    const total = runs.length;
    runs.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
    if (limit !== void 0 && offset !== void 0) {
      const start = offset;
      const end = start + limit;
      runs = runs.slice(start, end);
    }
    const parsedRuns = runs.map((run) => ({
      ...run,
      snapshot: typeof run.snapshot === "string" ? JSON.parse(run.snapshot) : JSON.parse(JSON.stringify(run.snapshot)),
      createdAt: new Date(run.createdAt),
      updatedAt: new Date(run.updatedAt),
      runId: run.run_id,
      workflowName: run.workflow_name
    }));
    return { runs: parsedRuns, total };
  }
  async getWorkflowRunById({
    runId,
    workflowName
  }) {
    let run = Array.from(this.collection.values()).find((r) => r.run_id === runId);
    if (run && workflowName && run.workflow_name !== workflowName) {
      run = void 0;
    }
    if (!run) return null;
    const parsedRun = {
      ...run,
      snapshot: typeof run.snapshot === "string" ? JSON.parse(run.snapshot) : JSON.parse(JSON.stringify(run.snapshot)),
      createdAt: new Date(run.createdAt),
      updatedAt: new Date(run.updatedAt),
      runId: run.run_id,
      workflowName: run.workflow_name
    };
    return parsedRun;
  }
};

// src/storage/mock.ts
var InMemoryStore = class extends MastraStorage {
  stores;
  constructor() {
    super({ name: "InMemoryStorage" });
    this.hasInitialized = Promise.resolve(true);
    const operationsStorage = new StoreOperationsInMemory();
    const database = operationsStorage.getDatabase();
    const scoresStorage = new ScoresInMemory({
      collection: database.mastra_scorers
    });
    const workflowsStorage = new WorkflowsInMemory({
      collection: database.mastra_workflow_snapshot,
      operations: operationsStorage
    });
    const tracesStorage = new TracesInMemory({
      collection: database.mastra_traces,
      operations: operationsStorage
    });
    const memoryStorage = new InMemoryMemory({
      collection: {
        threads: database.mastra_threads,
        resources: database.mastra_resources,
        messages: database.mastra_messages
      },
      operations: operationsStorage
    });
    const legacyEvalsStorage = new InMemoryLegacyEvals({
      collection: database.mastra_evals
    });
    const observabilityStorage = new ObservabilityInMemory({
      collection: database.mastra_ai_spans,
      operations: operationsStorage
    });
    this.stores = {
      legacyEvals: legacyEvalsStorage,
      operations: operationsStorage,
      workflows: workflowsStorage,
      traces: tracesStorage,
      scores: scoresStorage,
      memory: memoryStorage,
      observability: observabilityStorage
    };
  }
  get supports() {
    return {
      selectByIncludeResourceScope: false,
      resourceWorkingMemory: false,
      hasColumn: false,
      createTable: false,
      deleteMessages: true,
      aiTracing: true
    };
  }
  async persistWorkflowSnapshot({
    workflowName,
    runId,
    snapshot
  }) {
    await this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
  }
  async loadWorkflowSnapshot({
    workflowName,
    runId
  }) {
    return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
  }
  async createTable({
    tableName,
    schema
  }) {
    await this.stores.operations.createTable({ tableName, schema });
  }
  async alterTable({
    tableName,
    schema,
    ifNotExists
  }) {
    await this.stores.operations.alterTable({ tableName, schema, ifNotExists });
  }
  async clearTable({ tableName }) {
    await this.stores.operations.clearTable({ tableName });
  }
  async dropTable({ tableName }) {
    await this.stores.operations.dropTable({ tableName });
  }
  async insert({ tableName, record }) {
    await this.stores.operations.insert({ tableName, record });
  }
  async updateWorkflowResults({
    workflowName,
    runId,
    stepId,
    result,
    runtimeContext
  }) {
    return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
  }
  async updateWorkflowState({
    workflowName,
    runId,
    opts
  }) {
    return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
  }
  async batchInsert({ tableName, records }) {
    await this.stores.operations.batchInsert({ tableName, records });
  }
  async load({ tableName, keys }) {
    return this.stores.operations.load({ tableName, keys });
  }
  async getThreadById({ threadId }) {
    return this.stores.memory.getThreadById({ threadId });
  }
  async getThreadsByResourceId({
    resourceId,
    orderBy,
    sortDirection
  }) {
    return this.stores.memory.getThreadsByResourceId({ resourceId, orderBy, sortDirection });
  }
  async saveThread({ thread }) {
    return this.stores.memory.saveThread({ thread });
  }
  async updateThread({
    id,
    title,
    metadata
  }) {
    return this.stores.memory.updateThread({ id, title, metadata });
  }
  async deleteThread({ threadId }) {
    return this.stores.memory.deleteThread({ threadId });
  }
  async getResourceById({ resourceId }) {
    return this.stores.memory.getResourceById({ resourceId });
  }
  async saveResource({ resource }) {
    return this.stores.memory.saveResource({ resource });
  }
  async updateResource({
    resourceId,
    workingMemory,
    metadata
  }) {
    return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
  }
  async getMessages({
    threadId,
    resourceId,
    selectBy,
    format
  }) {
    return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
  }
  async getMessagesById({
    messageIds,
    format
  }) {
    return this.stores.memory.getMessagesById({ messageIds, format });
  }
  async saveMessages(args) {
    return this.stores.memory.saveMessages(args);
  }
  async updateMessages(args) {
    return this.stores.memory.updateMessages(args);
  }
  async deleteMessages(messageIds) {
    return this.stores.memory.deleteMessages(messageIds);
  }
  async getThreadsByResourceIdPaginated(args) {
    return this.stores.memory.getThreadsByResourceIdPaginated(args);
  }
  async getMessagesPaginated({
    threadId,
    selectBy
  }) {
    return this.stores.memory.getMessagesPaginated({ threadId, selectBy });
  }
  async getTraces({
    name,
    scope,
    page,
    perPage,
    attributes,
    filters,
    fromDate,
    toDate
  }) {
    return this.stores.traces.getTraces({ name, scope, page, perPage, attributes, filters, fromDate, toDate });
  }
  async getTracesPaginated(args) {
    return this.stores.traces.getTracesPaginated(args);
  }
  async batchTraceInsert(args) {
    return this.stores.traces.batchTraceInsert(args);
  }
  async getScoreById({ id }) {
    return this.stores.scores.getScoreById({ id });
  }
  async saveScore(score) {
    return this.stores.scores.saveScore(score);
  }
  async getScoresByScorerId({
    scorerId,
    entityId,
    entityType,
    source,
    pagination
  }) {
    return this.stores.scores.getScoresByScorerId({ scorerId, entityId, entityType, source, pagination });
  }
  async getScoresByRunId({
    runId,
    pagination
  }) {
    return this.stores.scores.getScoresByRunId({ runId, pagination });
  }
  async getScoresByEntityId({
    entityId,
    entityType,
    pagination
  }) {
    return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
  }
  async getEvals(options) {
    return this.stores.legacyEvals.getEvals(options);
  }
  async getEvalsByAgentName(agentName, type) {
    return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
  }
  async getWorkflowRuns({
    workflowName,
    fromDate,
    toDate,
    limit,
    offset,
    resourceId
  } = {}) {
    return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });
  }
  async getWorkflowRunById({
    runId,
    workflowName
  }) {
    return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
  }
  async createAISpan(span) {
    return this.stores.observability.createAISpan(span);
  }
  async updateAISpan(params) {
    return this.stores.observability.updateAISpan(params);
  }
  async getAITrace(traceId) {
    return this.stores.observability.getAITrace(traceId);
  }
  async batchCreateAISpans(args) {
    return this.stores.observability.batchCreateAISpans(args);
  }
  async batchUpdateAISpans(args) {
    return this.stores.observability.batchUpdateAISpans(args);
  }
  async batchDeleteAITraces(args) {
    return this.stores.observability.batchDeleteAITraces(args);
  }
};
var MockStore = InMemoryStore;

// src/storage/utils.ts
function safelyParseJSON(input) {
  if (input && typeof input === "object") return input;
  if (input == null) return {};
  if (typeof input === "string") {
    try {
      return JSON.parse(input);
    } catch {
      return input;
    }
  }
  return {};
}

export { InMemoryMemory, InMemoryStore, LegacyEvalsStorage, MemoryStorage, MockStore, ObservabilityInMemory, ObservabilityStorage, ScoresInMemory, ScoresStorage, StoreOperations, StoreOperationsInMemory, TracesInMemory, TracesStorage, WorkflowsInMemory, WorkflowsStorage, safelyParseJSON };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map