{"version":3,"file":"index.cjs","names":["TABLE_MESSAGES","TABLE_WORKFLOW_SNAPSHOT","MastraError","ErrorDomain","ErrorCategory","MemoryStorage","TABLE_THREADS","TABLE_MESSAGES","TABLE_RESOURCES","MastraError","ErrorDomain","ErrorCategory","MessageList","ScoresStorage","TABLE_SCORERS","MastraError","ErrorDomain","ErrorCategory","saveScorePayloadSchema","crypto","WorkflowsStorage","TABLE_WORKFLOW_SNAPSHOT","MastraError","ErrorDomain","ErrorCategory","MastraStorage","MastraServerCache"],"sources":["../src/storage/domains/utils.ts","../src/storage/db/index.ts","../src/storage/domains/memory/index.ts","../src/storage/domains/scores/index.ts","../src/storage/domains/workflows/index.ts","../src/storage/utils.ts","../src/storage/store.ts","../src/cache.ts"],"sourcesContent":["import { serializeDate, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT } from '@mastra/core/storage';\nimport type { TABLE_NAMES } from '@mastra/core/storage';\n\n/**\n * Generate a Redis key from table name and key parts.\n *\n * @example\n * ```typescript\n * getKey('mastra_threads', { id: 'thread-123' });\n * // Returns: 'mastra_threads:id:thread-123'\n *\n * getKey('mastra_messages', { threadId: 'thread-123', id: 'msg-456' });\n * // Returns: 'mastra_messages:threadId:thread-123:id:msg-456'\n * ```\n */\nexport function getKey(tableName: TABLE_NAMES, keys: Record<string, unknown>): string {\n  const keyParts = Object.entries(keys)\n    .filter(([_, value]) => value !== undefined)\n    .map(([key, value]) => {\n      if (value && typeof value === 'object') {\n        return `${key}:${JSON.stringify(value)}`;\n      }\n\n      return `${key}:${value}`;\n    });\n\n  return `${tableName}:${keyParts.join(':')}`;\n}\n\n/**\n * Process a record for storage, generating the appropriate key and serializing dates.\n */\nexport function processRecord(tableName: TABLE_NAMES, record: Record<string, unknown>) {\n  let key: string;\n\n  if (tableName === TABLE_MESSAGES) {\n    key = getKey(tableName, { threadId: record.threadId, id: record.id });\n  } else if (tableName === TABLE_WORKFLOW_SNAPSHOT) {\n    key = getKey(tableName, {\n      namespace: record.namespace || 'workflows',\n      workflow_name: record.workflow_name,\n      run_id: record.run_id,\n      ...(record.resourceId ? { resourceId: record.resourceId } : {}),\n    });\n  } else {\n    key = getKey(tableName, { id: record.id });\n  }\n\n  const processedRecord = {\n    ...record,\n    createdAt: serializeDate(record.createdAt as Date | string | undefined),\n    updatedAt: serializeDate(record.updatedAt as Date | string | undefined),\n  };\n\n  return { key, processedRecord };\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { createStorageErrorId } from '@mastra/core/storage';\nimport type { TABLE_NAMES } from '@mastra/core/storage';\n\nimport { getKey, processRecord } from '../domains/utils';\nimport type { RedisClient } from '../types';\n\nexport class RedisDB {\n  private client: RedisClient;\n\n  constructor({ client }: { client: RedisClient }) {\n    this.client = client;\n  }\n\n  getClient(): RedisClient {\n    return this.client;\n  }\n\n  async insert({ tableName, record }: { tableName: TABLE_NAMES; record: Record<string, unknown> }): Promise<void> {\n    const { key, processedRecord } = processRecord(tableName, record);\n\n    try {\n      await this.client.set(key, JSON.stringify(processedRecord));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'INSERT', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  async get<R>({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, string> }): Promise<R | null> {\n    const key = getKey(tableName, keys);\n    try {\n      const data = await this.client.get(key);\n      if (!data) {\n        return null;\n      }\n      return JSON.parse(data) as R;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LOAD', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  async scanAndDelete(pattern: string, batchSize = 10000): Promise<number> {\n    let cursor = '0';\n    let totalDeleted = 0;\n\n    do {\n      const result = await this.client.scan(cursor, { MATCH: pattern, COUNT: batchSize });\n\n      if (result.keys.length > 0) {\n        await this.client.del(result.keys);\n        totalDeleted += result.keys.length;\n      }\n\n      cursor = result.cursor;\n    } while (cursor !== '0');\n\n    return totalDeleted;\n  }\n\n  async scanKeys(pattern: string, batchSize = 10000): Promise<string[]> {\n    let cursor = '0';\n    const keys: string[] = [];\n\n    do {\n      const result = await this.client.scan(cursor, { MATCH: pattern, COUNT: batchSize });\n\n      keys.push(...result.keys);\n      cursor = result.cursor;\n    } while (cursor !== '0');\n\n    return keys;\n  }\n\n  async deleteData({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {\n    const pattern = `${tableName}:*`;\n    try {\n      await this.scanAndDelete(pattern);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'CLEAR_TABLE', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName,\n          },\n        },\n        error,\n      );\n    }\n  }\n}\n\nexport interface RedisDomainConfig {\n  client: RedisClient;\n}\n","import { MessageList } from '@mastra/core/agent';\nimport type { MastraMessageContentV2 } from '@mastra/core/agent';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport type { MastraDBMessage, StorageThreadType } from '@mastra/core/memory';\nimport {\n  MemoryStorage,\n  TABLE_RESOURCES,\n  TABLE_THREADS,\n  TABLE_MESSAGES,\n  normalizePerPage,\n  calculatePagination,\n  createStorageErrorId,\n  ensureDate,\n  filterByDateRange,\n  jsonValueEquals,\n  storageMessageMatchesMetadataFilter,\n  validateStorageMetadataFilter,\n} from '@mastra/core/storage';\nimport type {\n  StorageResourceType,\n  StorageListMessagesInput,\n  StorageListMessagesOutput,\n  StorageListThreadsInput,\n  StorageListThreadsOutput,\n  ThreadOrderBy,\n  ThreadSortDirection,\n  StorageCloneThreadInput,\n  StorageCloneThreadOutput,\n  ThreadCloneMetadata,\n} from '@mastra/core/storage';\n\nimport { RedisDB } from '../../db';\nimport type { RedisDomainConfig } from '../../db';\nimport type { RedisClient } from '../../types';\nimport { getKey, processRecord } from '../utils';\n\nexport class StoreMemoryRedis extends MemoryStorage {\n  override readonly supportsPartialThreadUpdate = true;\n  private client: RedisClient;\n  private db: RedisDB;\n\n  constructor(config: RedisDomainConfig) {\n    super();\n    this.client = config.client;\n    this.db = new RedisDB({ client: config.client });\n  }\n\n  public async dangerouslyClearAll(): Promise<void> {\n    await this.db.deleteData({ tableName: TABLE_THREADS });\n    await this.db.deleteData({ tableName: TABLE_MESSAGES });\n    await this.db.deleteData({ tableName: TABLE_RESOURCES });\n    await this.db.scanAndDelete('msg-idx:*');\n    await this.db.scanAndDelete('thread:*:messages');\n  }\n\n  public async getThreadById({\n    threadId,\n    resourceId,\n  }: {\n    threadId: string;\n    resourceId?: string;\n  }): Promise<StorageThreadType | null> {\n    try {\n      const thread = await this.db.get<StorageThreadType>({\n        tableName: TABLE_THREADS,\n        keys: { id: threadId },\n      });\n\n      if (!thread || (resourceId !== undefined && thread.resourceId !== resourceId)) {\n        return null;\n      }\n\n      return {\n        ...thread,\n        createdAt: ensureDate(thread.createdAt)!,\n        updatedAt: ensureDate(thread.updatedAt)!,\n        metadata: typeof thread.metadata === 'string' ? JSON.parse(thread.metadata) : thread.metadata,\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'GET_THREAD_BY_ID', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            threadId,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async listThreadsByResourceId(args: StorageListThreadsInput): Promise<StorageListThreadsOutput> {\n    return this.listThreads(args);\n  }\n\n  public async listThreads(args: StorageListThreadsInput): Promise<StorageListThreadsOutput> {\n    const { page = 0, perPage: perPageInput, orderBy, filter } = args;\n    const { field, direction } = this.parseOrderBy(orderBy);\n\n    try {\n      this.validatePaginationInput(page, perPageInput ?? 100);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LIST_THREADS', 'INVALID_PAGE'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { page, ...(perPageInput !== undefined && { perPage: perPageInput }) },\n        },\n        error instanceof Error ? error : new Error('Invalid pagination parameters'),\n      );\n    }\n\n    const perPage = normalizePerPage(perPageInput, 100);\n\n    try {\n      this.validateMetadataKeys(filter?.metadata);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LIST_THREADS', 'INVALID_METADATA_KEY'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(', ') : '' },\n        },\n        error instanceof Error ? error : new Error('Invalid metadata key'),\n      );\n    }\n\n    const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n    try {\n      let allThreads: StorageThreadType[] = [];\n      const pattern = `${TABLE_THREADS}:*`;\n      const keys = await this.db.scanKeys(pattern);\n\n      if (keys.length === 0) {\n        return {\n          threads: [],\n          total: 0,\n          page,\n          perPage: perPageForResponse,\n          hasMore: false,\n        };\n      }\n\n      const results = await this.client.mGet(keys);\n\n      for (let i = 0; i < results.length; i++) {\n        const data = results[i];\n        if (!data) {\n          continue;\n        }\n        const thread = JSON.parse(data) as StorageThreadType;\n\n        if (filter?.resourceId && thread.resourceId !== filter.resourceId) {\n          continue;\n        }\n\n        if (filter?.metadata && Object.keys(filter.metadata).length > 0) {\n          const threadMetadata = typeof thread.metadata === 'string' ? JSON.parse(thread.metadata) : thread.metadata;\n          const matches = Object.entries(filter.metadata).every(([key, value]) =>\n            jsonValueEquals(threadMetadata?.[key], value),\n          );\n          if (!matches) {\n            continue;\n          }\n        }\n\n        allThreads.push({\n          ...thread,\n          createdAt: ensureDate(thread.createdAt)!,\n          updatedAt: ensureDate(thread.updatedAt)!,\n          metadata: typeof thread.metadata === 'string' ? JSON.parse(thread.metadata) : thread.metadata,\n        });\n      }\n\n      const sortedThreads = this.sortThreads(allThreads, field, direction);\n      const total = sortedThreads.length;\n      const end = perPageInput === false ? total : offset + perPage;\n      const paginatedThreads = sortedThreads.slice(offset, end);\n      const hasMore = perPageInput === false ? false : end < total;\n\n      return {\n        threads: paginatedThreads,\n        total,\n        page,\n        perPage: perPageForResponse,\n        hasMore,\n      };\n    } catch (error) {\n      // Re-throw USER errors (validation errors) directly so callers get proper 400 responses\n      if (error instanceof MastraError && error.category === ErrorCategory.USER) {\n        throw error;\n      }\n      const mastraError = new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LIST_THREADS', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            ...(filter?.resourceId && { resourceId: filter.resourceId }),\n            hasMetadataFilter: !!filter?.metadata,\n            page,\n            perPage,\n          },\n        },\n        error,\n      );\n      this.logger.trackException(mastraError);\n      this.logger.error(mastraError.toString());\n      throw mastraError;\n    }\n  }\n\n  public async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {\n    try {\n      await this.db.insert({\n        tableName: TABLE_THREADS,\n        record: thread,\n      });\n      return thread;\n    } catch (error) {\n      const mastraError = new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'SAVE_THREAD', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            threadId: thread.id,\n          },\n        },\n        error,\n      );\n      this.logger.trackException(mastraError);\n      this.logger.error(mastraError.toString());\n      throw mastraError;\n    }\n  }\n\n  public async updateThread({\n    id,\n    title,\n    metadata,\n  }: {\n    id: string;\n    title?: string;\n    metadata?: Record<string, unknown>;\n  }): Promise<StorageThreadType> {\n    const thread = await this.getThreadById({ threadId: id });\n    if (!thread) {\n      throw new MastraError({\n        id: createStorageErrorId('REDIS', 'UPDATE_THREAD', 'FAILED'),\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        text: `Thread ${id} not found`,\n        details: {\n          threadId: id,\n        },\n      });\n    }\n\n    const updatedThread = {\n      ...thread,\n      title: title ?? thread.title,\n      metadata: {\n        ...thread.metadata,\n        ...metadata,\n      },\n      updatedAt: new Date(),\n    };\n\n    try {\n      await this.saveThread({ thread: updatedThread });\n      return updatedThread;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'UPDATE_THREAD', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            threadId: id,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async deleteThread({ threadId }: { threadId: string }): Promise<void> {\n    const threadKey = getKey(TABLE_THREADS, { id: threadId });\n    const threadMessagesKey = getThreadMessagesKey(threadId);\n\n    try {\n      const messageIds = await this.client.zRange(threadMessagesKey, 0, -1);\n\n      const multi = this.client.multi();\n      multi.del(threadKey);\n      multi.del(threadMessagesKey);\n\n      for (const messageId of messageIds) {\n        const messageKey = getMessageKey(threadId, messageId);\n        multi.del(messageKey);\n        multi.del(getMessageIndexKey(messageId));\n      }\n\n      await multi.exec();\n      await this.db.scanAndDelete(getMessageKey(threadId, '*'));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'DELETE_THREAD', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            threadId,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async saveMessages(args: { messages: MastraDBMessage[] }): Promise<{ messages: MastraDBMessage[] }> {\n    const { messages } = args;\n    if (messages.length === 0) {\n      return { messages: [] };\n    }\n\n    const threadId = messages[0]?.threadId;\n    try {\n      if (!threadId) {\n        throw new Error('Thread ID is required');\n      }\n      const thread = await this.getThreadById({ threadId });\n      if (!thread) {\n        throw new Error(`Thread ${threadId} not found`);\n      }\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'SAVE_MESSAGES', 'INVALID_ARGS'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n        },\n        error,\n      );\n    }\n\n    const messagesWithIndex = messages.map((message, index) => {\n      if (!message.threadId) {\n        throw new Error(\n          `Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`,\n        );\n      }\n      if (!message.resourceId) {\n        throw new Error(\n          `Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`,\n        );\n      }\n      return {\n        ...message,\n        _index: index,\n      };\n    });\n\n    const threadKey = getKey(TABLE_THREADS, { id: threadId });\n    const existingThreadData = await this.client.get(threadKey);\n    const existingThread = existingThreadData ? (JSON.parse(existingThreadData) as StorageThreadType) : null;\n\n    try {\n      const batchSize = 1000;\n      const existingThreadIds = await this.client.mGet(\n        messagesWithIndex.map(message => getMessageIndexKey(message.id)),\n      );\n\n      for (let i = 0; i < messagesWithIndex.length; i += batchSize) {\n        const batch = messagesWithIndex.slice(i, i + batchSize);\n        const batchExistingThreadIds = existingThreadIds.slice(i, i + batch.length);\n        const multi = this.client.multi();\n\n        for (const [batchIndex, message] of batch.entries()) {\n          const key = getMessageKey(message.threadId!, message.id);\n          const score = getMessageScore(message);\n          const existingThreadId = batchExistingThreadIds[batchIndex];\n\n          if (existingThreadId && existingThreadId !== message.threadId) {\n            const existingMessageKey = getMessageKey(existingThreadId, message.id);\n            multi.del(existingMessageKey);\n            multi.zRem(getThreadMessagesKey(existingThreadId), message.id);\n          }\n\n          multi.set(key, JSON.stringify(message));\n          multi.set(getMessageIndexKey(message.id), message.threadId!);\n          multi.zAdd(getThreadMessagesKey(message.threadId!), { score, value: message.id });\n        }\n\n        if (i === 0 && existingThread) {\n          const updatedThread = {\n            ...existingThread,\n            updatedAt: new Date(),\n          };\n          multi.set(threadKey, JSON.stringify(processRecord(TABLE_THREADS, updatedThread).processedRecord));\n        }\n\n        await multi.exec();\n      }\n\n      const list = new MessageList().add(messages as Parameters<MessageList['add']>[0], 'memory');\n      return { messages: list.get.all.db() };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'SAVE_MESSAGES', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            threadId,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  private async getThreadIdForMessage(messageId: string): Promise<string | null> {\n    const indexedThreadId = await this.client.get(getMessageIndexKey(messageId));\n    if (indexedThreadId) {\n      return indexedThreadId;\n    }\n\n    const keys = await this.db.scanKeys(getMessageKey('*', messageId));\n    if (keys.length === 0) {\n      return null;\n    }\n\n    const messageData = await this.client.get(keys[0] as string);\n    if (!messageData) {\n      return null;\n    }\n\n    const message = JSON.parse(messageData) as MastraDBMessage;\n    if (message.threadId) {\n      await this.client.set(getMessageIndexKey(messageId), message.threadId);\n    }\n\n    return message.threadId || null;\n  }\n\n  /**\n   * Fetches the messages named by `include` together with their surrounding context.\n   *\n   * @param include - Message ids to pin, each with an optional before/after window.\n   * @param resourceId - When set, drops any pinned or context message owned by another\n   * resource so an id from another resource returns nothing.\n   */\n  private async getIncludedMessages(\n    include: StorageListMessagesInput['include'],\n    resourceId?: string,\n  ): Promise<MastraDBMessage[]> {\n    if (!include?.length) {\n      return [];\n    }\n\n    const messageIds = new Set<string>();\n    const messageIdToThreadIds: Record<string, string> = {};\n\n    for (const item of include) {\n      const itemThreadId = await this.getThreadIdForMessage(item.id);\n      if (!itemThreadId) {\n        continue;\n      }\n\n      const itemThreadMessagesKey = getThreadMessagesKey(itemThreadId);\n\n      if (resourceId !== undefined) {\n        const threadMessageIds = await this.client.zRange(itemThreadMessagesKey, 0, -1);\n        const threadMessages = (await this.client.mGet(threadMessageIds.map(id => getMessageKey(itemThreadId, id))))\n          .filter((data): data is string => data !== null)\n          .map(data => JSON.parse(data) as MastraDBMessage)\n          .filter(message => message.resourceId === resourceId);\n        const targetIndex = threadMessages.findIndex(message => message.id === item.id);\n        if (targetIndex === -1) {\n          continue;\n        }\n\n        const start = Math.max(0, targetIndex - (item.withPreviousMessages ?? 0));\n        const end = Math.min(threadMessages.length, targetIndex + (item.withNextMessages ?? 0) + 1);\n        for (const message of threadMessages.slice(start, end)) {\n          messageIds.add(message.id);\n          messageIdToThreadIds[message.id] = itemThreadId;\n        }\n        continue;\n      }\n\n      messageIds.add(item.id);\n      messageIdToThreadIds[item.id] = itemThreadId;\n      const rank = await this.client.zRank(itemThreadMessagesKey, item.id);\n      if (rank === null) {\n        continue;\n      }\n\n      if (item.withPreviousMessages) {\n        const start = Math.max(0, rank - item.withPreviousMessages);\n        const prevIds = rank === 0 ? [] : await this.client.zRange(itemThreadMessagesKey, start, rank - 1);\n        prevIds.forEach(id => {\n          messageIds.add(id);\n          messageIdToThreadIds[id] = itemThreadId;\n        });\n      }\n\n      if (item.withNextMessages) {\n        const nextIds = await this.client.zRange(itemThreadMessagesKey, rank + 1, rank + item.withNextMessages);\n        nextIds.forEach(id => {\n          messageIds.add(id);\n          messageIdToThreadIds[id] = itemThreadId;\n        });\n      }\n    }\n\n    if (messageIds.size === 0) {\n      return [];\n    }\n\n    const keysToFetch = Array.from(messageIds).map(id => getMessageKey(messageIdToThreadIds[id]!, id));\n    const results = await this.client.mGet(keysToFetch);\n\n    const includedMessages = results\n      .filter((data): data is string => data !== null)\n      .map(data => JSON.parse(data) as MastraDBMessage);\n    return resourceId ? includedMessages.filter(message => message.resourceId === resourceId) : includedMessages;\n  }\n\n  private parseStoredMessage(storedMessage: MastraDBMessage & { _index?: number }): MastraDBMessage {\n    const defaultMessageContent = { format: 2, parts: [{ type: 'text', text: '' }] };\n    const { _index, ...rest } = storedMessage;\n    return {\n      ...rest,\n      createdAt: new Date(rest.createdAt),\n      content: rest.content || defaultMessageContent,\n    } satisfies MastraDBMessage;\n  }\n\n  public async listMessagesById({ messageIds }: { messageIds: string[] }): Promise<{ messages: MastraDBMessage[] }> {\n    if (messageIds.length === 0) {\n      return { messages: [] };\n    }\n\n    try {\n      const rawMessages: (MastraDBMessage & { _index?: number })[] = [];\n\n      const indexKeys = messageIds.map(id => getMessageIndexKey(id));\n      const indexResults = await this.client.mGet(indexKeys);\n\n      const indexedIds: { messageId: string; threadId: string }[] = [];\n      const unindexedIds: string[] = [];\n\n      messageIds.forEach((id, i) => {\n        const threadId = indexResults[i];\n        if (threadId) {\n          indexedIds.push({ messageId: id, threadId });\n          return;\n        }\n        unindexedIds.push(id);\n      });\n\n      if (indexedIds.length > 0) {\n        const messageKeys = indexedIds.map(({ messageId, threadId }) => getMessageKey(threadId, messageId));\n        const messageResults = await this.client.mGet(messageKeys);\n        for (const data of messageResults) {\n          if (data) {\n            rawMessages.push(JSON.parse(data) as MastraDBMessage & { _index?: number });\n          }\n        }\n      }\n\n      if (unindexedIds.length > 0) {\n        const threadKeys = await this.db.scanKeys('thread:*:messages');\n\n        const result = await Promise.all(\n          threadKeys.map(async threadKey => {\n            const threadId = threadKey.split(':')[1];\n            if (!threadId) {\n              throw new Error(`Failed to parse thread ID from thread key \"${threadKey}\"`);\n            }\n            const msgKeys = unindexedIds.map(id => getMessageKey(threadId, id));\n            return this.client.mGet(msgKeys);\n          }),\n        );\n\n        const foundMessages = result\n          .flat(1)\n          .filter((data): data is string => !!data)\n          .map(data => JSON.parse(data) as MastraDBMessage & { _index?: number });\n        rawMessages.push(...foundMessages);\n\n        if (foundMessages.length > 0) {\n          const multi = this.client.multi();\n          foundMessages.forEach(msg => {\n            if (msg.threadId) {\n              multi.set(getMessageIndexKey(msg.id), msg.threadId);\n            }\n          });\n          await multi.exec();\n        }\n      }\n\n      const list = new MessageList().add(rawMessages.map(this.parseStoredMessage), 'memory');\n      return { messages: list.get.all.db() };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LIST_MESSAGES_BY_ID', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            messageIds: JSON.stringify(messageIds),\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async listMessages(args: StorageListMessagesInput): Promise<StorageListMessagesOutput> {\n    const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;\n\n    const threadIds = Array.isArray(threadId) ? threadId : [threadId];\n    const threadIdsSet = new Set(threadIds);\n\n    if (threadIds.length === 0 || threadIds.some(id => !id.trim())) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LIST_MESSAGES', 'INVALID_THREAD_ID'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { threadId: Array.isArray(threadId) ? threadId.join(',') : threadId },\n        },\n        new Error('threadId must be a non-empty string or array of non-empty strings'),\n      );\n    }\n\n    const perPage = normalizePerPage(perPageInput, 40);\n    const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n    const metadataFilter = validateStorageMetadataFilter(filter?.metadata);\n\n    try {\n      if (page < 0) {\n        throw new MastraError(\n          {\n            id: createStorageErrorId('REDIS', 'LIST_MESSAGES', 'INVALID_PAGE'),\n            domain: ErrorDomain.STORAGE,\n            category: ErrorCategory.USER,\n            details: { page },\n          },\n          new Error('page must be >= 0'),\n        );\n      }\n\n      const { field, direction } = this.parseOrderBy(orderBy, 'ASC');\n\n      const getFieldValue = (msg: MastraDBMessage): number => {\n        if (field === 'createdAt') {\n          return new Date(msg.createdAt).getTime();\n        }\n\n        const value = (msg as Record<string, unknown>)[field];\n        if (typeof value === 'number') {\n          return value;\n        }\n        if (value instanceof Date) {\n          return value.getTime();\n        }\n        return 0;\n      };\n\n      if (perPage === 0 && (!include || include.length === 0)) {\n        return {\n          messages: [],\n          total: 0,\n          page,\n          perPage: perPageForResponse,\n          hasMore: false,\n        };\n      }\n\n      let includedMessages: MastraDBMessage[] = [];\n      if (include && include.length > 0) {\n        const included = (await this.getIncludedMessages(include, resourceId)) as MastraDBMessage[];\n        includedMessages = included.map(this.parseStoredMessage);\n      }\n\n      if (perPage === 0 && include && include.length > 0) {\n        const list = new MessageList().add(includedMessages, 'memory');\n        const messages = list.get.all.db().sort((a, b) => {\n          const aValue = getFieldValue(a);\n          const bValue = getFieldValue(b);\n          return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n        });\n\n        return {\n          messages,\n          total: 0,\n          page,\n          perPage: perPageForResponse,\n          hasMore: false,\n        };\n      }\n\n      const allMessageIdsWithThreads: { threadId: string; messageId: string }[] = [];\n      for (const tid of threadIds) {\n        const threadMessagesKey = getThreadMessagesKey(tid);\n        const msgIds = await this.client.zRange(threadMessagesKey, 0, -1);\n        for (const mid of msgIds) {\n          allMessageIdsWithThreads.push({ threadId: tid, messageId: mid });\n        }\n      }\n\n      if (allMessageIdsWithThreads.length === 0) {\n        return {\n          messages: [],\n          total: 0,\n          page,\n          perPage: perPageForResponse,\n          hasMore: false,\n        };\n      }\n\n      const messageKeys = allMessageIdsWithThreads.map(({ threadId: tid, messageId }) => getMessageKey(tid, messageId));\n      const results = await this.client.mGet(messageKeys);\n\n      let messagesData = results\n        .filter((data): data is string => data !== null)\n        .map(data => JSON.parse(data) as MastraDBMessage & { _index?: number })\n        .map(this.parseStoredMessage);\n\n      if (resourceId) {\n        messagesData = messagesData.filter(msg => msg.resourceId === resourceId);\n      }\n\n      messagesData = filterByDateRange(\n        messagesData,\n        (msg: MastraDBMessage) => new Date(msg.createdAt),\n        filter?.dateRange,\n      );\n\n      messagesData = messagesData.filter(message =>\n        storageMessageMatchesMetadataFilter(message.content, metadataFilter),\n      );\n\n      messagesData.sort((a, b) => {\n        const aValue = getFieldValue(a);\n        const bValue = getFieldValue(b);\n        return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n      });\n\n      const total = messagesData.length;\n      const start = offset;\n      const end = perPageInput === false ? total : start + perPage;\n      const paginatedMessages = messagesData.slice(start, end);\n\n      const messageIdsSet = new Set<string>();\n      const allMessages: MastraDBMessage[] = [];\n\n      for (const msg of paginatedMessages) {\n        if (messageIdsSet.has(msg.id)) {\n          continue;\n        }\n        allMessages.push(msg);\n        messageIdsSet.add(msg.id);\n      }\n\n      for (const msg of includedMessages) {\n        if (messageIdsSet.has(msg.id)) {\n          continue;\n        }\n        allMessages.push(msg);\n        messageIdsSet.add(msg.id);\n      }\n\n      const list = new MessageList().add(allMessages, 'memory');\n      let finalMessages = list.get.all.db();\n\n      finalMessages = finalMessages.sort((a, b) => {\n        const aValue = getFieldValue(a);\n        const bValue = getFieldValue(b);\n        return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n      });\n\n      const returnedThreadMessageIds = new Set(\n        finalMessages\n          .filter(message => message.threadId && threadIdsSet.has(message.threadId))\n          .map(message => message.id),\n      );\n      const hasMore =\n        perPageInput !== false &&\n        (metadataFilter || returnedThreadMessageIds.size < total) &&\n        offset + paginatedMessages.length < total;\n\n      return {\n        messages: finalMessages,\n        total,\n        page,\n        perPage: perPageForResponse,\n        hasMore,\n      };\n    } catch (error) {\n      // Re-throw USER errors (validation errors) directly so callers get proper 400 responses\n      if (error instanceof MastraError && error.category === ErrorCategory.USER) {\n        throw error;\n      }\n      const mastraError = new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LIST_MESSAGES', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            threadId: Array.isArray(threadId) ? threadId.join(',') : threadId,\n            resourceId: resourceId ?? '',\n          },\n        },\n        error,\n      );\n      this.logger.error(mastraError.toString());\n      this.logger.trackException(mastraError);\n      throw mastraError;\n    }\n  }\n\n  public async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {\n    try {\n      const key = `${TABLE_RESOURCES}:${resourceId}`;\n      const data = await this.client.get(key);\n      if (!data) {\n        return null;\n      }\n\n      const resource = JSON.parse(data) as StorageResourceType;\n\n      return {\n        ...resource,\n        createdAt: new Date(resource.createdAt),\n        updatedAt: new Date(resource.updatedAt),\n        workingMemory:\n          typeof resource.workingMemory === 'object' ? JSON.stringify(resource.workingMemory) : resource.workingMemory,\n        metadata: typeof resource.metadata === 'string' ? JSON.parse(resource.metadata) : resource.metadata,\n      };\n    } catch (error) {\n      this.logger.error('Error getting resource by ID:', error);\n      throw error;\n    }\n  }\n\n  public async saveResource({ resource }: { resource: StorageResourceType }): Promise<StorageResourceType> {\n    try {\n      const key = `${TABLE_RESOURCES}:${resource.id}`;\n      const serializedResource = {\n        ...resource,\n        metadata: JSON.stringify(resource.metadata),\n        createdAt: resource.createdAt.toISOString(),\n        updatedAt: resource.updatedAt.toISOString(),\n      };\n\n      await this.client.set(key, JSON.stringify(serializedResource));\n\n      return resource;\n    } catch (error) {\n      this.logger.error('Error saving resource:', error);\n      throw error;\n    }\n  }\n\n  public async updateResource({\n    resourceId,\n    workingMemory,\n    metadata,\n  }: {\n    resourceId: string;\n    workingMemory?: string;\n    metadata?: Record<string, unknown>;\n  }): Promise<StorageResourceType> {\n    try {\n      const existingResource = await this.getResourceById({ resourceId });\n\n      if (!existingResource) {\n        const newResource: StorageResourceType = {\n          id: resourceId,\n          workingMemory,\n          metadata: metadata || {},\n          createdAt: new Date(),\n          updatedAt: new Date(),\n        };\n        return this.saveResource({ resource: newResource });\n      }\n\n      const updatedResource = {\n        ...existingResource,\n        workingMemory: workingMemory !== undefined ? workingMemory : existingResource.workingMemory,\n        metadata: {\n          ...existingResource.metadata,\n          ...metadata,\n        },\n        updatedAt: new Date(),\n      };\n\n      await this.saveResource({ resource: updatedResource });\n      return updatedResource;\n    } catch (error) {\n      this.logger.error('Error updating resource:', error);\n      throw error;\n    }\n  }\n\n  public async updateMessages(args: {\n    messages: (Partial<Omit<MastraDBMessage, 'createdAt'>> & {\n      id: string;\n      content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };\n    })[];\n  }): Promise<MastraDBMessage[]> {\n    const { messages } = args;\n    if (messages.length === 0) {\n      return [];\n    }\n\n    try {\n      const messageIds = messages.map(m => m.id);\n      const existingMessages: MastraDBMessage[] = [];\n      const messageIdToKey: Record<string, string> = {};\n\n      for (const messageId of messageIds) {\n        const pattern = getMessageKey('*', messageId);\n        const keys = await this.db.scanKeys(pattern);\n\n        for (const key of keys) {\n          const data = await this.client.get(key);\n          if (!data) {\n            continue;\n          }\n          const message = JSON.parse(data) as MastraDBMessage;\n          if (message && message.id === messageId) {\n            existingMessages.push(message);\n            messageIdToKey[messageId] = key;\n            break;\n          }\n        }\n      }\n\n      if (existingMessages.length === 0) {\n        return [];\n      }\n\n      const threadIdsToUpdate = new Set<string>();\n      const multi = this.client.multi();\n\n      for (const existingMessage of existingMessages) {\n        const updatePayload = messages.find(m => m.id === existingMessage.id);\n        if (!updatePayload) {\n          continue;\n        }\n\n        const { id, ...fieldsToUpdate } = updatePayload;\n        if (Object.keys(fieldsToUpdate).length === 0) {\n          continue;\n        }\n\n        threadIdsToUpdate.add(existingMessage.threadId!);\n        if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {\n          threadIdsToUpdate.add(updatePayload.threadId);\n        }\n\n        const updatedMessage = { ...existingMessage };\n\n        if (fieldsToUpdate.content) {\n          const existingContent = existingMessage.content as MastraMessageContentV2;\n          const newContent = {\n            ...existingContent,\n            ...fieldsToUpdate.content,\n            ...(existingContent?.metadata && fieldsToUpdate.content.metadata\n              ? {\n                  metadata: {\n                    ...existingContent.metadata,\n                    ...fieldsToUpdate.content.metadata,\n                  },\n                }\n              : {}),\n          };\n          updatedMessage.content = newContent;\n        }\n\n        for (const key in fieldsToUpdate) {\n          if (Object.prototype.hasOwnProperty.call(fieldsToUpdate, key) && key !== 'content') {\n            (updatedMessage as Record<string, unknown>)[key] = fieldsToUpdate[key as keyof typeof fieldsToUpdate];\n          }\n        }\n\n        const key = messageIdToKey[id];\n        if (!key) {\n          continue;\n        }\n\n        if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {\n          multi.zRem(getThreadMessagesKey(existingMessage.threadId!), id);\n          multi.del(key);\n\n          const newKey = getMessageKey(updatePayload.threadId, id);\n          multi.set(newKey, JSON.stringify(updatedMessage));\n          multi.set(getMessageIndexKey(id), updatePayload.threadId);\n\n          const score = getMessageScore(updatedMessage as MastraDBMessage & { _index?: number });\n          multi.zAdd(getThreadMessagesKey(updatePayload.threadId), { score, value: id });\n\n          messageIdToKey[id] = newKey;\n          continue;\n        }\n\n        multi.set(key, JSON.stringify(updatedMessage));\n      }\n\n      const now = new Date();\n      for (const threadId of threadIdsToUpdate) {\n        if (threadId) {\n          const threadKey = getKey(TABLE_THREADS, { id: threadId });\n          const existingThreadData = await this.client.get(threadKey);\n          if (existingThreadData) {\n            const existingThread = JSON.parse(existingThreadData) as StorageThreadType;\n            const updatedThread = {\n              ...existingThread,\n              updatedAt: now,\n            };\n            multi.set(threadKey, JSON.stringify(processRecord(TABLE_THREADS, updatedThread).processedRecord));\n          }\n        }\n      }\n\n      await multi.exec();\n\n      const updatedMessages: MastraDBMessage[] = [];\n      for (const messageId of messageIds) {\n        const key = messageIdToKey[messageId];\n        if (key) {\n          const data = await this.client.get(key);\n          if (data) {\n            updatedMessages.push(JSON.parse(data) as MastraDBMessage);\n          }\n        }\n      }\n\n      return updatedMessages;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'UPDATE_MESSAGES', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            messageIds: messages.map(m => m.id).join(','),\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async deleteMessages(messageIds: string[]): Promise<void> {\n    if (!messageIds || messageIds.length === 0) {\n      return;\n    }\n\n    try {\n      const threadIds = new Set<string>();\n      const messageKeys: string[] = [];\n      const foundMessageIds: string[] = [];\n      const messageIdToThreadId = new Map<string, string>();\n\n      const indexKeys = messageIds.map(id => getMessageIndexKey(id));\n      const indexResults = await this.client.mGet(indexKeys);\n\n      const indexedMessages: { messageId: string; threadId: string }[] = [];\n      const unindexedMessageIds: string[] = [];\n\n      messageIds.forEach((id, i) => {\n        const threadId = indexResults[i];\n        if (threadId) {\n          indexedMessages.push({ messageId: id, threadId });\n          return;\n        }\n        unindexedMessageIds.push(id);\n      });\n\n      for (const { messageId, threadId } of indexedMessages) {\n        messageKeys.push(getMessageKey(threadId, messageId));\n        foundMessageIds.push(messageId);\n        messageIdToThreadId.set(messageId, threadId);\n        threadIds.add(threadId);\n      }\n\n      for (const messageId of unindexedMessageIds) {\n        const pattern = getMessageKey('*', messageId);\n        const keys = await this.db.scanKeys(pattern);\n\n        for (const key of keys) {\n          const data = await this.client.get(key);\n          if (!data) {\n            continue;\n          }\n          const message = JSON.parse(data) as MastraDBMessage;\n          if (message && message.id === messageId) {\n            messageKeys.push(key);\n            foundMessageIds.push(messageId);\n            if (message.threadId) {\n              messageIdToThreadId.set(messageId, message.threadId);\n              threadIds.add(message.threadId);\n            }\n            break;\n          }\n        }\n      }\n\n      if (messageKeys.length === 0) {\n        return;\n      }\n\n      const multi = this.client.multi();\n\n      for (const key of messageKeys) {\n        multi.del(key);\n      }\n\n      for (const messageId of foundMessageIds) {\n        multi.del(getMessageIndexKey(messageId));\n      }\n\n      if (threadIds.size > 0) {\n        for (const threadId of threadIds) {\n          for (const [msgId, msgThreadId] of messageIdToThreadId) {\n            if (msgThreadId === threadId) {\n              multi.zRem(getThreadMessagesKey(threadId), msgId);\n            }\n          }\n\n          const threadKey = getKey(TABLE_THREADS, { id: threadId });\n          const threadData = await this.client.get(threadKey);\n          if (!threadData) {\n            continue;\n          }\n\n          const thread = JSON.parse(threadData) as StorageThreadType;\n          const updatedThread = { ...thread, updatedAt: new Date() };\n          multi.set(threadKey, JSON.stringify(processRecord(TABLE_THREADS, updatedThread).processedRecord));\n        }\n      }\n\n      await multi.exec();\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'DELETE_MESSAGES', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { messageIds: messageIds.join(', ') },\n        },\n        error,\n      );\n    }\n  }\n\n  private sortThreads(\n    threads: StorageThreadType[],\n    field: ThreadOrderBy,\n    direction: ThreadSortDirection,\n  ): StorageThreadType[] {\n    return threads.sort((a, b) => {\n      const aValue = new Date(a[field]).getTime();\n      const bValue = new Date(b[field]).getTime();\n      return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n    });\n  }\n\n  public async cloneThread(args: StorageCloneThreadInput): Promise<StorageCloneThreadOutput> {\n    const { sourceThreadId, newThreadId: providedThreadId, resourceId, title, metadata, options } = args;\n\n    const sourceThread = await this.getThreadById({ threadId: sourceThreadId });\n    if (!sourceThread) {\n      throw new MastraError({\n        id: createStorageErrorId('REDIS', 'CLONE_THREAD', 'SOURCE_NOT_FOUND'),\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        text: `Source thread with id ${sourceThreadId} not found`,\n        details: { sourceThreadId },\n      });\n    }\n\n    const newThreadId = providedThreadId || crypto.randomUUID();\n\n    const existingThread = await this.getThreadById({ threadId: newThreadId });\n    if (existingThread) {\n      throw new MastraError({\n        id: createStorageErrorId('REDIS', 'CLONE_THREAD', 'THREAD_EXISTS'),\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        text: `Thread with id ${newThreadId} already exists`,\n        details: { newThreadId },\n      });\n    }\n\n    try {\n      const threadMessagesKey = getThreadMessagesKey(sourceThreadId);\n      const msgIds = await this.client.zRange(threadMessagesKey, 0, -1);\n\n      const messageKeys = msgIds.map(mid => getMessageKey(sourceThreadId, mid));\n      let sourceMessages: (MastraDBMessage & { _index?: number })[] = [];\n\n      if (messageKeys.length > 0) {\n        const results = await this.client.mGet(messageKeys);\n        sourceMessages = results\n          .filter((data): data is string => data !== null)\n          .map(data => {\n            const msg = JSON.parse(data) as MastraDBMessage & { _index?: number };\n            return { ...msg, createdAt: new Date(msg.createdAt) };\n          });\n      }\n\n      if (options?.messageFilter?.startDate || options?.messageFilter?.endDate) {\n        sourceMessages = filterByDateRange(sourceMessages, (msg: MastraDBMessage) => new Date(msg.createdAt), {\n          start: options.messageFilter?.startDate,\n          end: options.messageFilter?.endDate,\n        });\n      }\n\n      if (options?.messageFilter?.messageIds && options.messageFilter.messageIds.length > 0) {\n        const messageIdSet = new Set(options.messageFilter.messageIds);\n        sourceMessages = sourceMessages.filter(msg => messageIdSet.has(msg.id));\n      }\n\n      sourceMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());\n\n      if (options?.messageLimit && options.messageLimit > 0 && sourceMessages.length > options.messageLimit) {\n        sourceMessages = sourceMessages.slice(-options.messageLimit);\n      }\n\n      const now = new Date();\n      const lastMessageId = sourceMessages.length > 0 ? sourceMessages[sourceMessages.length - 1]!.id : undefined;\n\n      const cloneMetadata: ThreadCloneMetadata = {\n        sourceThreadId,\n        clonedAt: now,\n        ...(lastMessageId && { lastMessageId }),\n      };\n\n      const newThread: StorageThreadType = {\n        id: newThreadId,\n        resourceId: resourceId || sourceThread.resourceId,\n        title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : undefined),\n        metadata: { ...metadata, clone: cloneMetadata },\n        createdAt: now,\n        updatedAt: now,\n      };\n\n      const multi = this.client.multi();\n      const threadKey = getKey(TABLE_THREADS, { id: newThreadId });\n      multi.set(threadKey, JSON.stringify(processRecord(TABLE_THREADS, newThread).processedRecord));\n\n      const clonedMessages: MastraDBMessage[] = [];\n      const messageIdMap: Record<string, string> = Object.create(null);\n      const targetResourceId = resourceId || sourceThread.resourceId;\n      const newThreadMessagesKey = getThreadMessagesKey(newThreadId);\n\n      for (let i = 0; i < sourceMessages.length; i++) {\n        const sourceMsg = sourceMessages[i]!;\n        const newMessageId = crypto.randomUUID();\n        const { _index, ...restMsg } = sourceMsg;\n\n        const newMessage: MastraDBMessage = {\n          ...restMsg,\n          id: newMessageId,\n          threadId: newThreadId,\n          resourceId: targetResourceId,\n        };\n\n        const messageKey = getMessageKey(newThreadId, newMessageId);\n        multi.set(messageKey, JSON.stringify(newMessage));\n        multi.set(getMessageIndexKey(newMessageId), newThreadId);\n        const score = getMessageScore({ createdAt: newMessage.createdAt, _index: i });\n        multi.zAdd(newThreadMessagesKey, { score, value: newMessageId });\n\n        clonedMessages.push(newMessage);\n        messageIdMap[sourceMsg.id] = newMessageId;\n      }\n\n      await multi.exec();\n\n      return {\n        thread: newThread,\n        clonedMessages,\n        messageIdMap,\n      };\n    } catch (error) {\n      if (error instanceof MastraError) {\n        throw error;\n      }\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'CLONE_THREAD', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { sourceThreadId, newThreadId },\n        },\n        error,\n      );\n    }\n  }\n}\n\nfunction getThreadMessagesKey(threadId: string): string {\n  return `thread:${threadId}:messages`;\n}\n\nfunction getMessageKey(threadId: string, messageId: string): string {\n  return getKey(TABLE_MESSAGES, { threadId, id: messageId });\n}\n\nfunction getMessageIndexKey(messageId: string): string {\n  return `msg-idx:${messageId}`;\n}\n\nfunction getMessageScore(message: { createdAt: Date | string; _index?: number }): number {\n  const createdAtScore = new Date(message.createdAt).getTime();\n  const index = typeof message._index === 'number' ? message._index : 0;\n  return createdAtScore * 1000 + index;\n}\n","import crypto from 'node:crypto';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport type { SaveScorePayload, ScoreRowData, ScoringSource } from '@mastra/core/evals';\nimport { saveScorePayloadSchema } from '@mastra/core/evals';\nimport {\n  calculatePagination,\n  normalizePerPage,\n  ScoresStorage,\n  TABLE_SCORERS,\n  transformScoreRow,\n  createStorageErrorId,\n} from '@mastra/core/storage';\nimport type { PaginationInfo, StoragePagination, ScoreTenancyFilters } from '@mastra/core/storage';\n\nimport { RedisDB } from '../../db';\nimport type { RedisDomainConfig } from '../../db';\nimport type { RedisClient } from '../../types';\nimport { processRecord } from '../utils';\n\n/** Returns true when a row matches the multi-tenant scope filters (or none provided). */\nfunction matchesTenancy(row: Record<string, unknown>, filters?: ScoreTenancyFilters): boolean {\n  if (filters?.organizationId !== undefined && row.organizationId !== filters.organizationId) return false;\n  if (filters?.projectId !== undefined && row.projectId !== filters.projectId) return false;\n  return true;\n}\n\nexport class ScoresRedis extends ScoresStorage {\n  private client: RedisClient;\n  private db: RedisDB;\n\n  constructor(config: RedisDomainConfig) {\n    super();\n    this.client = config.client;\n    this.db = new RedisDB({ client: config.client });\n  }\n\n  public async dangerouslyClearAll(): Promise<void> {\n    await this.db.deleteData({ tableName: TABLE_SCORERS });\n  }\n\n  public async getScoreById({ id }: { id: string }): Promise<ScoreRowData | null> {\n    try {\n      const data = await this.db.get<ScoreRowData>({\n        tableName: TABLE_SCORERS,\n        keys: { id },\n      });\n\n      if (!data) {\n        return null;\n      }\n\n      return transformScoreRow(data as Record<string, unknown>);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'GET_SCORE_BY_ID', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            ...(id && { id }),\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async listScoresByScorerId({\n    scorerId,\n    entityId,\n    entityType,\n    source,\n    pagination = { page: 0, perPage: 20 },\n    filters,\n  }: {\n    scorerId: string;\n    entityId?: string;\n    entityType?: string;\n    source?: ScoringSource;\n    pagination?: StoragePagination;\n    filters?: ScoreTenancyFilters;\n  }): Promise<{\n    scores: ScoreRowData[];\n    pagination: PaginationInfo;\n  }> {\n    return this.fetchAndFilterScores(pagination, row => {\n      if (row.scorerId !== scorerId) {\n        return false;\n      }\n      if (entityId && row.entityId !== entityId) {\n        return false;\n      }\n      if (entityType && row.entityType !== entityType) {\n        return false;\n      }\n      if (source && row.source !== source) {\n        return false;\n      }\n      if (!matchesTenancy(row, filters)) {\n        return false;\n      }\n      return true;\n    });\n  }\n\n  public async saveScore(score: SaveScorePayload): Promise<{ score: ScoreRowData }> {\n    let validatedScore: SaveScorePayload;\n    try {\n      validatedScore = saveScorePayloadSchema.parse(score);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'SAVE_SCORE', 'VALIDATION_FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: {\n            scorer: typeof score.scorer?.id === 'string' ? score.scorer.id : String(score.scorer?.id ?? 'unknown'),\n            entityId: score.entityId ?? 'unknown',\n            entityType: score.entityType ?? 'unknown',\n            traceId: score.traceId ?? '',\n            spanId: score.spanId ?? '',\n          },\n        },\n        error,\n      );\n    }\n\n    const now = new Date();\n    const id = crypto.randomUUID();\n\n    const scoreWithId = {\n      ...validatedScore,\n      id,\n      createdAt: now,\n      updatedAt: now,\n    };\n\n    const { key, processedRecord } = processRecord(TABLE_SCORERS, scoreWithId);\n    try {\n      await this.client.set(key, JSON.stringify(processedRecord));\n      return { score: { ...validatedScore, id, createdAt: now, updatedAt: now } as ScoreRowData };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'SAVE_SCORE', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { id },\n        },\n        error,\n      );\n    }\n  }\n\n  public async listScoresByRunId({\n    runId,\n    pagination = { page: 0, perPage: 20 },\n    filters,\n  }: {\n    runId: string;\n    pagination?: StoragePagination;\n    filters?: ScoreTenancyFilters;\n  }): Promise<{\n    scores: ScoreRowData[];\n    pagination: PaginationInfo;\n  }> {\n    return this.fetchAndFilterScores(pagination, row => row.runId === runId && matchesTenancy(row, filters));\n  }\n\n  public async listScoresByEntityId({\n    entityId,\n    entityType,\n    pagination = { page: 0, perPage: 20 },\n    filters,\n  }: {\n    entityId: string;\n    entityType?: string;\n    pagination?: StoragePagination;\n    filters?: ScoreTenancyFilters;\n  }): Promise<{\n    scores: ScoreRowData[];\n    pagination: PaginationInfo;\n  }> {\n    return this.fetchAndFilterScores(pagination, row => {\n      if (row.entityId !== entityId) {\n        return false;\n      }\n      if (entityType && row.entityType !== entityType) {\n        return false;\n      }\n      if (!matchesTenancy(row, filters)) {\n        return false;\n      }\n      return true;\n    });\n  }\n\n  public async listScoresBySpan({\n    traceId,\n    spanId,\n    pagination = { page: 0, perPage: 20 },\n    filters,\n  }: {\n    traceId: string;\n    spanId: string;\n    pagination?: StoragePagination;\n    filters?: ScoreTenancyFilters;\n  }): Promise<{\n    scores: ScoreRowData[];\n    pagination: PaginationInfo;\n  }> {\n    return this.fetchAndFilterScores(\n      pagination,\n      row => row.traceId === traceId && row.spanId === spanId && matchesTenancy(row, filters),\n    );\n  }\n\n  private async fetchAndFilterScores(\n    pagination: StoragePagination,\n    filterFn: (row: Record<string, unknown>) => boolean,\n  ): Promise<{ scores: ScoreRowData[]; pagination: PaginationInfo }> {\n    const { page, perPage: perPageInput } = pagination;\n    const keys = await this.db.scanKeys(`${TABLE_SCORERS}:*`);\n\n    if (keys.length === 0) {\n      return {\n        scores: [],\n        pagination: { total: 0, page, perPage: perPageInput, hasMore: false },\n      };\n    }\n\n    const results = await this.client.mGet(keys);\n\n    const filtered = results\n      .map((data): Record<string, unknown> | null => {\n        if (!data) {\n          return null;\n        }\n        try {\n          return JSON.parse(data) as Record<string, unknown>;\n        } catch {\n          return null;\n        }\n      })\n      .filter((row): row is Record<string, unknown> => !!row && typeof row === 'object' && filterFn(row));\n\n    const total = filtered.length;\n    const perPage = normalizePerPage(perPageInput, 100);\n    const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n    const end = perPageInput === false ? total : start + perPage;\n    const scores = filtered.slice(start, end).map(row => transformScoreRow(row));\n\n    return {\n      scores,\n      pagination: {\n        total,\n        page,\n        perPage: perPageForResponse,\n        hasMore: end < total,\n      },\n    };\n  }\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport {\n  createStorageErrorId,\n  normalizePerPage,\n  TABLE_WORKFLOW_SNAPSHOT,\n  matchesExpectedWorkflowStatus,\n  WorkflowsStorage,\n  ensureDate,\n} from '@mastra/core/storage';\nimport type {\n  StorageListWorkflowRunsInput,\n  WorkflowRun,\n  WorkflowRuns,\n  UpdateWorkflowStateOptions,\n} from '@mastra/core/storage';\nimport type { StepResult, WorkflowRunState } from '@mastra/core/workflows';\n\nimport { RedisDB } from '../../db';\nimport type { RedisDomainConfig } from '../../db';\nimport type { RedisClient } from '../../types';\nimport { getKey } from '../utils';\n\nfunction parseWorkflowRun(row: Record<string, unknown>): WorkflowRun {\n  let parsedSnapshot: WorkflowRunState | string = row.snapshot as string;\n  if (typeof parsedSnapshot === 'string') {\n    try {\n      parsedSnapshot = JSON.parse(row.snapshot as string) as WorkflowRunState;\n    } catch (e) {\n      console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);\n    }\n  }\n\n  return {\n    workflowName: row.workflow_name as string,\n    runId: row.run_id as string,\n    snapshot: parsedSnapshot,\n    createdAt: ensureDate(row.createdAt as string | Date)!,\n    updatedAt: ensureDate(row.updatedAt as string | Date)!,\n    resourceId: row.resourceId as string | undefined,\n  };\n}\n\nexport class WorkflowsRedis extends WorkflowsStorage {\n  private client: RedisClient;\n  private db: RedisDB;\n\n  constructor(config: RedisDomainConfig) {\n    super();\n    this.client = config.client;\n    this.db = new RedisDB({ client: config.client });\n  }\n\n  public supportsConcurrentUpdates(): boolean {\n    return false;\n  }\n\n  public async dangerouslyClearAll(): Promise<void> {\n    await this.db.deleteData({ tableName: TABLE_WORKFLOW_SNAPSHOT });\n  }\n\n  public async updateWorkflowResults({\n    workflowName,\n    runId,\n    stepId,\n    result,\n    requestContext,\n  }: {\n    workflowName: string;\n    runId: string;\n    stepId: string;\n    result: StepResult<unknown, unknown, unknown, unknown>;\n    requestContext: Record<string, unknown>;\n  }): Promise<Record<string, StepResult<unknown, unknown, unknown, unknown>>> {\n    try {\n      const existingRecord = await this.db.get<{\n        namespace: string;\n        workflow_name: string;\n        run_id: string;\n        snapshot: WorkflowRunState;\n        createdAt: string | Date;\n        updatedAt: string | Date;\n      }>({\n        tableName: TABLE_WORKFLOW_SNAPSHOT,\n        keys: {\n          namespace: 'workflows',\n          workflow_name: workflowName,\n          run_id: runId,\n        },\n      });\n\n      const existingSnapshot = existingRecord?.snapshot;\n      let snapshot = existingSnapshot;\n\n      if (!snapshot) {\n        snapshot = {\n          context: {},\n          activePaths: [],\n          timestamp: Date.now(),\n          suspendedPaths: {},\n          activeStepsPath: {},\n          resumeLabels: {},\n          serializedStepGraph: [],\n          status: 'pending',\n          value: {},\n          waitingPaths: {},\n          runId,\n          requestContext: {},\n        } as WorkflowRunState;\n      }\n\n      snapshot.context[stepId] = result;\n      snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };\n\n      await this.persistWorkflowSnapshot({\n        namespace: 'workflows',\n        workflowName,\n        runId,\n        snapshot,\n        createdAt: existingRecord?.createdAt ? ensureDate(existingRecord.createdAt) : undefined,\n      });\n\n      return snapshot.context;\n    } catch (error) {\n      if (error instanceof MastraError) {\n        throw error;\n      }\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'UPDATE_WORKFLOW_RESULTS', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { workflowName, runId, stepId },\n        },\n        error,\n      );\n    }\n  }\n\n  public async updateWorkflowState({\n    workflowName,\n    runId,\n    opts,\n  }: {\n    workflowName: string;\n    runId: string;\n    opts: UpdateWorkflowStateOptions;\n  }): Promise<WorkflowRunState | undefined> {\n    try {\n      const existingRecord = await this.db.get<{\n        namespace: string;\n        workflow_name: string;\n        run_id: string;\n        snapshot: WorkflowRunState;\n        createdAt: string | Date;\n        updatedAt: string | Date;\n      }>({\n        tableName: TABLE_WORKFLOW_SNAPSHOT,\n        keys: {\n          namespace: 'workflows',\n          workflow_name: workflowName,\n          run_id: runId,\n        },\n      });\n\n      const existingSnapshot = existingRecord?.snapshot;\n\n      if (!existingSnapshot || !existingSnapshot.context) {\n        return undefined;\n      }\n\n      // Best-effort only: this store reports `supportsConcurrentUpdates() === false`, so the\n      // read and the write are not a single critical section.\n      const { expectedStatus, ...state } = opts;\n      if (!matchesExpectedWorkflowStatus(existingSnapshot.status, expectedStatus)) {\n        return undefined;\n      }\n\n      const updatedSnapshot = { ...existingSnapshot, ...state };\n\n      await this.persistWorkflowSnapshot({\n        namespace: 'workflows',\n        workflowName,\n        runId,\n        snapshot: updatedSnapshot,\n        createdAt: existingRecord?.createdAt ? ensureDate(existingRecord.createdAt) : undefined,\n      });\n\n      return updatedSnapshot;\n    } catch (error) {\n      if (error instanceof MastraError) {\n        throw error;\n      }\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'UPDATE_WORKFLOW_STATE', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { workflowName, runId },\n        },\n        error,\n      );\n    }\n  }\n\n  public async persistWorkflowSnapshot(params: {\n    namespace?: string;\n    workflowName: string;\n    runId: string;\n    resourceId?: string;\n    snapshot: WorkflowRunState;\n    createdAt?: Date;\n    updatedAt?: Date;\n  }): Promise<void> {\n    const { namespace = 'workflows', workflowName, runId, resourceId, snapshot, createdAt, updatedAt } = params;\n    try {\n      let finalCreatedAt = createdAt;\n      if (!finalCreatedAt) {\n        const existing = await this.db.get<{\n          namespace: string;\n          workflow_name: string;\n          run_id: string;\n          snapshot: WorkflowRunState;\n          createdAt: string | Date;\n          updatedAt: string | Date;\n        }>({\n          tableName: TABLE_WORKFLOW_SNAPSHOT,\n          keys: {\n            namespace,\n            workflow_name: workflowName,\n            run_id: runId,\n          },\n        });\n        finalCreatedAt = existing?.createdAt ? ensureDate(existing.createdAt) : new Date();\n      }\n\n      await this.db.insert({\n        tableName: TABLE_WORKFLOW_SNAPSHOT,\n        record: {\n          namespace,\n          workflow_name: workflowName,\n          run_id: runId,\n          resourceId,\n          snapshot,\n          createdAt: finalCreatedAt,\n          updatedAt: updatedAt ?? new Date(),\n        },\n      });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'PERSIST_WORKFLOW_SNAPSHOT', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            namespace,\n            workflowName,\n            runId,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async loadWorkflowSnapshot(params: {\n    namespace: string;\n    workflowName: string;\n    runId: string;\n  }): Promise<WorkflowRunState | null> {\n    const { namespace = 'workflows', workflowName, runId } = params;\n    const key = getKey(TABLE_WORKFLOW_SNAPSHOT, {\n      namespace,\n      workflow_name: workflowName,\n      run_id: runId,\n    });\n    try {\n      const data = await this.client.get(key);\n      if (!data) {\n        return null;\n      }\n      const parsed = JSON.parse(data) as {\n        namespace: string;\n        workflow_name: string;\n        run_id: string;\n        snapshot: WorkflowRunState;\n      };\n      return parsed.snapshot;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LOAD_WORKFLOW_SNAPSHOT', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            namespace,\n            workflowName,\n            runId,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async getWorkflowRunById({\n    runId,\n    workflowName,\n  }: {\n    runId: string;\n    workflowName?: string;\n  }): Promise<WorkflowRun | null> {\n    try {\n      const key =\n        getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace: 'workflows', workflow_name: workflowName, run_id: runId }) + '*';\n      const keys = await this.db.scanKeys(key);\n\n      if (keys.length === 0) {\n        return null;\n      }\n\n      const results = await this.client.mGet(keys);\n      const workflows = results\n        .filter((data): data is string => data !== null)\n        .map(\n          data =>\n            JSON.parse(data) as {\n              workflow_name: string;\n              run_id: string;\n              snapshot: WorkflowRunState | string;\n              createdAt: string | Date;\n              updatedAt: string | Date;\n              resourceId: string;\n            },\n        );\n\n      const data = workflows.find(workflow => {\n        if (!workflow) {\n          return false;\n        }\n\n        const runIdMatch = workflow.run_id === runId;\n\n        if (workflowName) {\n          return runIdMatch && workflow.workflow_name === workflowName;\n        }\n\n        return runIdMatch;\n      });\n\n      if (!data) {\n        return null;\n      }\n\n      return parseWorkflowRun(data as Record<string, unknown>);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'GET_WORKFLOW_RUN_BY_ID', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            namespace: 'workflows',\n            runId,\n            workflowName: workflowName || '',\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async deleteWorkflowRunById({ runId, workflowName }: { runId: string; workflowName: string }): Promise<void> {\n    const key = getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace: 'workflows', workflow_name: workflowName, run_id: runId });\n    try {\n      await this.client.del(key);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'DELETE_WORKFLOW_RUN_BY_ID', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            namespace: 'workflows',\n            runId,\n            workflowName,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public async listWorkflowRuns({\n    workflowName,\n    fromDate,\n    toDate,\n    perPage,\n    page,\n    resourceId,\n    status,\n  }: StorageListWorkflowRunsInput = {}): Promise<WorkflowRuns> {\n    try {\n      if (page !== undefined && page < 0) {\n        throw new MastraError(\n          {\n            id: createStorageErrorId('REDIS', 'LIST_WORKFLOW_RUNS', 'INVALID_PAGE'),\n            domain: ErrorDomain.STORAGE,\n            category: ErrorCategory.USER,\n            details: { page },\n          },\n          new Error('page must be >= 0'),\n        );\n      }\n\n      const normalizedFrom = fromDate ? ensureDate(fromDate) : undefined;\n      const normalizedTo = toDate ? ensureDate(toDate) : undefined;\n\n      let pattern = getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace: 'workflows' }) + ':*';\n      if (workflowName && resourceId) {\n        pattern = getKey(TABLE_WORKFLOW_SNAPSHOT, {\n          namespace: 'workflows',\n          workflow_name: workflowName,\n          run_id: '*',\n          resourceId,\n        });\n      } else if (workflowName) {\n        pattern = getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace: 'workflows', workflow_name: workflowName }) + ':*';\n      } else if (resourceId) {\n        pattern = getKey(TABLE_WORKFLOW_SNAPSHOT, {\n          namespace: 'workflows',\n          workflow_name: '*',\n          run_id: '*',\n          resourceId,\n        });\n      }\n      const keys = await this.db.scanKeys(pattern);\n\n      if (keys.length === 0) {\n        return { runs: [], total: 0 };\n      }\n\n      const results = await this.client.mGet(keys);\n\n      let runs = results\n        .filter((data): data is string => data !== null)\n        .map(data => JSON.parse(data) as Record<string, unknown>)\n        .filter(\n          (record): record is Record<string, unknown> =>\n            record !== null && record !== undefined && typeof record === 'object' && 'workflow_name' in record,\n        )\n        .filter(record => !workflowName || record.workflow_name === workflowName)\n        .map(w => parseWorkflowRun(w))\n        .filter(w => {\n          if (normalizedFrom && w.createdAt < normalizedFrom) {\n            return false;\n          }\n          if (normalizedTo && w.createdAt > normalizedTo) {\n            return false;\n          }\n          if (status) {\n            let snapshot = w.snapshot;\n            if (typeof snapshot === 'string') {\n              try {\n                snapshot = JSON.parse(snapshot) as WorkflowRunState;\n              } catch (e) {\n                console.warn(`Failed to parse snapshot for workflow ${w.workflowName}: ${e}`);\n                return false;\n              }\n            }\n            return snapshot.status === status;\n          }\n          return true;\n        })\n        .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n      const total = runs.length;\n\n      if (typeof perPage === 'number' && typeof page === 'number') {\n        const normalizedPerPage = normalizePerPage(perPage, Number.MAX_SAFE_INTEGER);\n        const offset = page * normalizedPerPage;\n        runs = runs.slice(offset, offset + normalizedPerPage);\n      }\n\n      return { runs, total };\n    } catch (error) {\n      if (error instanceof MastraError) {\n        throw error;\n      }\n      throw new MastraError(\n        {\n          id: createStorageErrorId('REDIS', 'LIST_WORKFLOW_RUNS', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            namespace: 'workflows',\n            workflowName: workflowName || '',\n            resourceId: resourceId || '',\n          },\n        },\n        error,\n      );\n    }\n  }\n}\n","import type { RedisClient, RedisConfig } from './types';\n\nexport function isClientConfig(config: RedisConfig): config is RedisConfig & { client: RedisClient } {\n  return 'client' in config;\n}\n\nexport function isConnectionStringConfig(config: RedisConfig): config is RedisConfig & { connectionString: string } {\n  return 'connectionString' in config;\n}\n","import { MastraStorage } from '@mastra/core/storage';\nimport type { StorageDomains } from '@mastra/core/storage';\nimport { createClient } from 'redis';\n\nimport { StoreMemoryRedis } from './domains/memory';\nimport { ScoresRedis } from './domains/scores';\nimport { WorkflowsRedis } from './domains/workflows';\nimport type { RedisClient, RedisConfig } from './types';\nimport { isClientConfig, isConnectionStringConfig } from './utils';\n\n/**\n * Redis storage adapter for Mastra.\n *\n * Provides storage functionality for direct Redis connections using the official redis package.\n *\n * Access domain-specific storage via `getStore()`:\n *\n * @example\n * ```typescript\n * // Using connection string\n * const storage = new RedisStore({\n *   id: 'my-store',\n *   connectionString: 'redis://localhost:6379',\n * });\n *\n * // Using host/port\n * const storage = new RedisStore({\n *   id: 'my-store',\n *   host: 'localhost',\n *   port: 6379,\n *   password: 'secret',\n * });\n *\n * // Access memory domain\n * const memory = await storage.getStore('memory');\n * await memory?.saveThread({ thread });\n *\n * // Access workflows domain\n * const workflows = await storage.getStore('workflows');\n * await workflows?.persistWorkflowSnapshot({ workflowName, runId, snapshot });\n * ```\n *\n * @example\n * ```typescript\n * // Using a pre-configured client for advanced features\n * import { createClient } from 'redis';\n *\n * const client = createClient({\n *   url: 'redis://localhost:6379',\n *   socket: {\n *     reconnectStrategy: (retries) => Math.min(retries * 50, 2000),\n *   },\n * });\n * await client.connect();\n *\n * const storage = new RedisStore({\n *   id: 'my-store',\n *   client,\n * });\n * ```\n */\nexport class RedisStore extends MastraStorage {\n  private client: RedisClient;\n  private shouldManageConnection: boolean;\n  public stores: StorageDomains;\n\n  constructor(config: RedisConfig) {\n    super({ id: config.id, name: 'Redis', disableInit: config.disableInit });\n\n    const { client, shouldManageConnection } = this.createClient(config);\n    this.client = client;\n    this.shouldManageConnection = shouldManageConnection;\n\n    this.stores = {\n      scores: new ScoresRedis({ client: this.client }),\n      workflows: new WorkflowsRedis({ client: this.client }),\n      memory: new StoreMemoryRedis({ client: this.client }),\n    };\n  }\n\n  public override async init(): Promise<void> {\n    if (this.shouldManageConnection && !this.client.isOpen) {\n      await this.client.connect();\n    }\n    await super.init();\n  }\n\n  public getClient(): RedisClient {\n    return this.client;\n  }\n\n  public async close(): Promise<void> {\n    if (this.shouldManageConnection && this.client.isOpen) {\n      await this.client.quit();\n    }\n  }\n\n  private createClient(config: RedisConfig): { client: RedisClient; shouldManageConnection: boolean } {\n    if (isClientConfig(config)) {\n      return { client: config.client, shouldManageConnection: false };\n    }\n\n    if (isConnectionStringConfig(config)) {\n      if (!config.connectionString?.trim()) {\n        throw new Error('RedisStore: connectionString is required and cannot be empty.');\n      }\n      return {\n        client: createClient({ url: config.connectionString }) as RedisClient,\n        shouldManageConnection: true,\n      };\n    }\n\n    if (!config.host?.trim()) {\n      throw new Error('RedisStore: host is required and cannot be empty.');\n    }\n\n    const url = this.createClientUrl({\n      ...config,\n      db: config.db ?? 0,\n      port: config.port ?? 6379,\n    });\n\n    return {\n      client: createClient({ url }) as RedisClient,\n      shouldManageConnection: true,\n    };\n  }\n\n  private createClientUrl(config: { host: string; password?: string; port: number; db: number }): string {\n    const encodedPassword = config.password ? encodeURIComponent(config.password) : null;\n\n    if (config.password) {\n      return `redis://:${encodedPassword}@${config.host}:${config.port || 6379}/${config.db || 0}`;\n    }\n\n    return `redis://${config.host}:${config.port || 6379}/${config.db || 0}`;\n  }\n}\n","import { MastraServerCache } from '@mastra/core/cache';\n\nexport interface RedisClient {\n  get(key: string): Promise<unknown>;\n  set(key: string, value: unknown, ...args: unknown[]): Promise<unknown>;\n  llen(key: string): Promise<number>;\n  rpush(key: string, ...values: unknown[]): Promise<number>;\n  lrange(key: string, start: number, stop: number): Promise<unknown[]>;\n  del(...keys: string[]): Promise<number>;\n  expire(key: string, seconds: number): Promise<number | boolean>;\n  scan(cursor: string | number, ...args: unknown[]): Promise<[string | number, string[]]>;\n  incr(key: string): Promise<number>;\n  /**\n   * Server-side Lua scripting. Optional: clients without it fall back to the\n   * two-round-trip `increment` + `listPush` path for `listPushIndexed`.\n   */\n  eval?(...args: unknown[]): Promise<unknown>;\n}\n\nexport interface RedisServerCacheOptions {\n  keyPrefix?: string;\n  ttlSeconds?: number;\n  /**\n   * Run a Lua script with the given KEYS and ARGV. Defaults to the ioredis\n   * calling convention (`eval(script, numKeys, ...keys, ...args)`); use\n   * `nodeRedisPreset` / `upstashPreset` for those clients.\n   */\n  evalScript?: (client: RedisClient, script: string, keys: string[], args: string[]) => Promise<unknown>;\n  setWithExpiry?: (client: RedisClient, key: string, value: unknown, seconds: number) => Promise<unknown>;\n  scanKeys?: (\n    client: RedisClient,\n    cursor: string | number,\n    pattern: string,\n    count: number,\n  ) => Promise<[string | number, string[]]>;\n  getListLength?: (client: RedisClient, key: string) => Promise<number>;\n  pushToList?: (client: RedisClient, key: string, value: unknown) => Promise<number>;\n  getListRange?: (client: RedisClient, key: string, start: number, stop: number) => Promise<unknown[]>;\n}\n\nconst defaultSetWithExpiry = (client: RedisClient, key: string, value: unknown, seconds: number): Promise<unknown> => {\n  return client.set(key, value, 'EX', seconds);\n};\n\nconst defaultScanKeys = (\n  client: RedisClient,\n  cursor: string | number,\n  pattern: string,\n  count: number,\n): Promise<[string | number, string[]]> => {\n  return client.scan(cursor, 'MATCH', pattern, 'COUNT', count);\n};\n\nconst defaultGetListLength = (client: RedisClient, key: string): Promise<number> => {\n  return client.llen(key);\n};\n\nconst defaultPushToList = (client: RedisClient, key: string, value: unknown): Promise<number> => {\n  return client.rpush(key, value);\n};\n\nconst defaultGetListRange = (client: RedisClient, key: string, start: number, stop: number): Promise<unknown[]> => {\n  return client.lrange(key, start, stop);\n};\n\nconst defaultEvalScript = (client: RedisClient, script: string, keys: string[], args: string[]): Promise<unknown> => {\n  return client.eval!(script, keys.length, ...keys, ...args);\n};\n\n/**\n * Atomic \"allocate index + append + refresh TTLs\" used by `listPushIndexed`.\n *\n * KEYS[1] = list key, KEYS[2] = counter key\n * ARGV[1] = JSON-serialized object WITHOUT an `index` property\n * ARGV[2] = TTL in seconds (0 = no expiry)\n *\n * The index is spliced into the JSON text as the first property rather than\n * decoded/re-encoded with cjson, which would silently alter large integers\n * and sparse arrays. `JSON.stringify` of an object always starts with `{`,\n * so `{...}` → `{\"index\":N,...}` and `{}` → `{\"index\":N}`.\n */\nexport const LIST_PUSH_INDEXED_SCRIPT = `\nlocal i = redis.call('INCR', KEYS[2]) - 1\nlocal body = ARGV[1]\nlocal doc\nif #body <= 2 then\n  doc = '{\"index\":' .. i .. '}'\nelse\n  doc = '{\"index\":' .. i .. ',' .. string.sub(body, 2)\nend\nredis.call('RPUSH', KEYS[1], doc)\nlocal ttl = tonumber(ARGV[2])\nif ttl > 0 then\n  redis.call('EXPIRE', KEYS[1], ttl)\n  redis.call('EXPIRE', KEYS[2], ttl)\nend\nreturn i\n`.trim();\n\nexport class RedisServerCache extends MastraServerCache {\n  private client: RedisClient;\n  private keyPrefix: string;\n  private ttlSeconds: number;\n  private setWithExpiry: (client: RedisClient, key: string, value: unknown, seconds: number) => Promise<unknown>;\n  private scanKeys: (\n    client: RedisClient,\n    cursor: string | number,\n    pattern: string,\n    count: number,\n  ) => Promise<[string | number, string[]]>;\n  private getListLength: (client: RedisClient, key: string) => Promise<number>;\n  private pushToList: (client: RedisClient, key: string, value: unknown) => Promise<number>;\n  private getListRange: (client: RedisClient, key: string, start: number, stop: number) => Promise<unknown[]>;\n  private evalScript: (client: RedisClient, script: string, keys: string[], args: string[]) => Promise<unknown>;\n  /** Set once scripting is known to be unusable (no `eval`, or Cluster CROSSSLOT). */\n  private scriptingDisabled: boolean;\n\n  constructor(config: { client: RedisClient }, options: RedisServerCacheOptions = {}) {\n    super({ name: 'RedisServerCache' });\n\n    this.client = config.client;\n    this.keyPrefix = options.keyPrefix ?? 'mastra:cache:';\n    this.ttlSeconds = options.ttlSeconds ?? 300;\n    this.setWithExpiry = options.setWithExpiry ?? defaultSetWithExpiry;\n    this.scanKeys = options.scanKeys ?? defaultScanKeys;\n    this.getListLength = options.getListLength ?? defaultGetListLength;\n    this.pushToList = options.pushToList ?? defaultPushToList;\n    this.getListRange = options.getListRange ?? defaultGetListRange;\n    this.evalScript = options.evalScript ?? defaultEvalScript;\n    this.scriptingDisabled = typeof this.client.eval !== 'function';\n  }\n\n  private getKey(key: string): string {\n    return `${this.keyPrefix}${key}`;\n  }\n\n  private serialize(value: unknown): string {\n    return JSON.stringify(value);\n  }\n\n  private deserialize(value: unknown): unknown {\n    if (typeof value === 'string') {\n      try {\n        return JSON.parse(value);\n      } catch {\n        return value;\n      }\n    }\n    return value;\n  }\n\n  async get(key: string): Promise<unknown> {\n    const fullKey = this.getKey(key);\n    const value = await this.client.get(fullKey);\n    if (value === null) {\n      return null;\n    }\n    return this.deserialize(value);\n  }\n\n  async set(key: string, value: unknown, ttlMs?: number): Promise<void> {\n    const fullKey = this.getKey(key);\n    const serialized = this.serialize(value);\n    const overrideSeconds = ttlMs !== undefined ? Math.max(1, Math.ceil(ttlMs / 1000)) : undefined;\n    const effectiveSeconds = overrideSeconds ?? this.ttlSeconds;\n    if (effectiveSeconds > 0) {\n      await this.setWithExpiry(this.client, fullKey, serialized, effectiveSeconds);\n    } else {\n      await this.client.set(fullKey, serialized);\n    }\n  }\n\n  async listLength(key: string): Promise<number> {\n    const fullKey = this.getKey(key);\n    return this.getListLength(this.client, fullKey);\n  }\n\n  async listPush(key: string, value: unknown): Promise<void> {\n    const fullKey = this.getKey(key);\n    const serialized = this.serialize(value);\n    await this.pushToList(this.client, fullKey, serialized);\n\n    if (this.ttlSeconds > 0) {\n      await this.client.expire(fullKey, this.ttlSeconds);\n    }\n  }\n\n  async listFromTo(key: string, from: number, to: number = -1): Promise<unknown[]> {\n    const fullKey = this.getKey(key);\n    const values = await this.getListRange(this.client, fullKey, from, to);\n    return values.map(v => this.deserialize(v));\n  }\n\n  async delete(key: string): Promise<void> {\n    const fullKey = this.getKey(key);\n    await this.client.del(fullKey);\n  }\n\n  async clear(): Promise<void> {\n    const pattern = `${this.keyPrefix}*`;\n    let cursor: string | number = '0';\n\n    do {\n      const [nextCursor, keys] = await this.scanKeys(this.client, cursor, pattern, 100);\n\n      if (keys.length > 0) {\n        await this.client.del(...keys);\n      }\n\n      cursor = nextCursor;\n    } while (cursor !== '0' && cursor !== 0);\n  }\n\n  async increment(key: string): Promise<number> {\n    const fullKey = this.getKey(key);\n    const value = await this.client.incr(fullKey);\n\n    if (this.ttlSeconds > 0) {\n      await this.client.expire(fullKey, this.ttlSeconds);\n    }\n\n    return value;\n  }\n\n  /**\n   * Single round-trip index allocation + list append + TTL refresh via Lua.\n   * This is the durable stream per-chunk hot path (issue #22477): the composed\n   * default costs four awaited commands (INCR, EXPIRE, RPUSH, EXPIRE).\n   */\n  async listPushIndexed(listKey: string, counterKey: string, value: Record<string, unknown>): Promise<number> {\n    if (this.scriptingDisabled) {\n      return super.listPushIndexed(listKey, counterKey, value);\n    }\n\n    const { index: _ignored, ...body } = value;\n    try {\n      const result = await this.evalScript(\n        this.client,\n        LIST_PUSH_INDEXED_SCRIPT,\n        [this.getKey(listKey), this.getKey(counterKey)],\n        [this.serialize(body), String(this.ttlSeconds)],\n      );\n      return Number(result);\n    } catch (error) {\n      // Redis Cluster rejects multi-key scripts whose keys hash to different\n      // slots. The list and counter keys are not hash-tagged (changing that\n      // would rename existing keys), so degrade to the composed path instead\n      // of losing replay caching entirely.\n      if (error instanceof Error && error.message.includes('CROSSSLOT')) {\n        this.scriptingDisabled = true;\n        this.logger.warn(\n          '[RedisServerCache] listPushIndexed script rejected with CROSSSLOT; falling back to increment + listPush',\n        );\n        return super.listPushIndexed(listKey, counterKey, value);\n      }\n      throw error;\n    }\n  }\n}\n\nexport const upstashPreset: Pick<RedisServerCacheOptions, 'setWithExpiry' | 'scanKeys' | 'evalScript'> = {\n  setWithExpiry: (client, key, value, seconds) => client.set(key, value, { ex: seconds } as any),\n  scanKeys: (client, cursor, pattern, count) =>\n    client.scan(cursor, { match: pattern, count } as any) as Promise<[string | number, string[]]>,\n  evalScript: (client, script, keys, args) => client.eval!(script, keys, args),\n};\n\n// node-redis v4+ exposes Redis multi-word commands as camelCase only\n// (lLen / rPush / lRange), not as lowercase aliases. The defaults in this\n// module use ioredis-style lowercase, so node-redis users need adapters that\n// forward to the camelCase methods. Single-word commands (set, scan, del,\n// expire, incr, get) work in lowercase under node-redis and don't need\n// adapters; the existing setWithExpiry / scanKeys adapters only exist to\n// reshape arguments, not to alias method names.\nexport const nodeRedisPreset: Pick<\n  RedisServerCacheOptions,\n  'setWithExpiry' | 'scanKeys' | 'getListLength' | 'pushToList' | 'getListRange' | 'evalScript'\n> = {\n  setWithExpiry: (client, key, value, seconds) => client.set(key, value, { EX: seconds } as any),\n  scanKeys: (client, cursor, pattern, count) =>\n    client.scan(cursor, { MATCH: pattern, COUNT: count } as any) as Promise<[string | number, string[]]>,\n  getListLength: (client, key) => (client as any).lLen(key),\n  pushToList: (client, key, value) => (client as any).rPush(key, value),\n  getListRange: (client, key, start, stop) => (client as any).lRange(key, start, stop),\n  evalScript: (client, script, keys, args) => client.eval!(script, { keys, arguments: args }),\n};\n"],"mappings":"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"}