{"version":3,"file":"index.cjs","names":["RedisServerCache","Redis","upstashPreset","TABLE_MESSAGES","TABLE_WORKFLOW_SNAPSHOT","TABLE_SCORERS","Redis","MastraError","ErrorDomain","ErrorCategory","BackgroundTasksStorage","#db","TABLE_BACKGROUND_TASKS","TABLE_MESSAGES","MemoryStorage","#db","TABLE_THREADS","TABLE_RESOURCES","MastraError","ErrorDomain","ErrorCategory","MessageList","ScoresStorage","#db","TABLE_SCORERS","MastraError","ErrorDomain","ErrorCategory","saveScorePayloadSchema","WorkflowsStorage","#db","TABLE_WORKFLOW_SNAPSHOT","MastraError","ErrorDomain","ErrorCategory","MastraCompositeStore","Redis","BaseFilterTranslator","MastraVector","Index","MastraError","ErrorDomain","ErrorCategory","upstashUpdate"],"sources":["../src/cache/index.ts","../src/storage/domains/utils.ts","../src/storage/db/index.ts","../src/storage/domains/background-tasks/index.ts","../src/storage/domains/memory/index.ts","../src/storage/domains/scores/index.ts","../src/storage/domains/workflows/index.ts","../src/storage/index.ts","../src/vector/filter.ts","../src/vector/index.ts","../src/vector/prompt.ts"],"sourcesContent":["import { RedisServerCache, upstashPreset } from '@mastra/redis';\nimport type { RedisClient, RedisServerCacheOptions } from '@mastra/redis';\nimport { Redis } from '@upstash/redis';\n\n/**\n * Configuration for UpstashServerCache.\n * Accepts either:\n * 1. An existing Redis client from @upstash/redis\n * 2. URL and token to create a client (requires @upstash/redis to be installed)\n */\nexport type UpstashCacheConfig = { client: Redis } | { url: string; token: string };\n\n/**\n * Options for UpstashServerCache\n */\nexport interface UpstashServerCacheOptions {\n  /**\n   * Optional key prefix to namespace all cache keys.\n   * Defaults to 'mastra:cache:'.\n   */\n  keyPrefix?: string;\n\n  /**\n   * Default TTL in seconds for cached items.\n   * Defaults to 300 (5 minutes).\n   * Set to 0 to disable TTL (items persist until explicitly deleted).\n   */\n  ttlSeconds?: number;\n}\n\n/**\n * Upstash Redis implementation of MastraServerCache.\n *\n * This is a convenience wrapper around RedisServerCache from @mastra/redis\n * with the upstash preset pre-configured.\n *\n * @example With existing client\n * ```typescript\n * import { Redis } from '@upstash/redis';\n * import { UpstashServerCache } from '@mastra/upstash';\n *\n * const redis = new Redis({ url: '...', token: '...' });\n * const cache = new UpstashServerCache({ client: redis });\n * ```\n *\n * @example With URL and token\n * ```typescript\n * import { UpstashServerCache } from '@mastra/upstash';\n *\n * const cache = new UpstashServerCache({\n *   url: process.env.UPSTASH_REDIS_REST_URL!,\n *   token: process.env.UPSTASH_REDIS_REST_TOKEN!,\n * });\n * ```\n */\nexport class UpstashServerCache extends RedisServerCache {\n  constructor(config: UpstashCacheConfig, options: UpstashServerCacheOptions = {}) {\n    let client: RedisClient;\n\n    if ('client' in config) {\n      client = config.client;\n    } else {\n      client = new Redis({ url: config.url, token: config.token });\n    }\n\n    const redisOptions: RedisServerCacheOptions = {\n      ...upstashPreset,\n      keyPrefix: options.keyPrefix,\n      ttlSeconds: options.ttlSeconds,\n    };\n\n    super({ client }, redisOptions);\n  }\n}\n\n// Re-export the generic types for convenience\nexport { RedisServerCache, upstashPreset, type RedisClient, type RedisServerCacheOptions } from '@mastra/redis';\n","import { serializeDate, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_SCORERS } from '@mastra/core/storage';\nimport type { TABLE_NAMES } from '@mastra/core/storage';\n\nexport function getKey(tableName: TABLE_NAMES, keys: Record<string, any>): string {\n  const keyParts = Object.entries(keys)\n    .filter(([_, value]) => value !== undefined)\n    .map(([key, value]) => `${key}:${value}`);\n  return `${tableName}:${keyParts.join(':')}`;\n}\n\nexport function processRecord(tableName: TABLE_NAMES, record: Record<string, any>) {\n  let key: string;\n\n  if (tableName === TABLE_MESSAGES) {\n    // For messages, use threadId as the primary key component\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 if (tableName === TABLE_SCORERS) {\n    key = getKey(tableName, { id: record.id });\n  } else {\n    key = getKey(tableName, { id: record.id });\n  }\n\n  // Convert dates to ISO strings before storing\n  const processedRecord = {\n    ...record,\n    createdAt: serializeDate(record.createdAt),\n    updatedAt: serializeDate(record.updatedAt),\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';\nimport { Redis } from '@upstash/redis';\nimport { getKey, processRecord } from '../domains/utils';\n\n/**\n * Configuration for standalone domain usage.\n * Accepts either:\n * 1. An existing Redis client\n * 2. Config to create a new client internally\n */\nexport type UpstashDomainConfig = UpstashDomainClientConfig | UpstashDomainRestConfig;\n\n/**\n * Pass an existing Redis client\n */\nexport interface UpstashDomainClientConfig {\n  client: Redis;\n}\n\n/**\n * Pass config to create a new Redis client internally\n */\nexport interface UpstashDomainRestConfig {\n  url: string;\n  token: string;\n}\n\n/**\n * Resolves UpstashDomainConfig to a Redis client.\n * Handles creating a new Redis client if url/token are provided.\n */\nexport function resolveUpstashConfig(config: UpstashDomainConfig): Redis {\n  // Existing client\n  if ('client' in config) {\n    return config.client;\n  }\n\n  // Config to create new client\n  return new Redis({\n    url: config.url,\n    token: config.token,\n  });\n}\n\nexport class UpstashDB {\n  private client: Redis;\n\n  constructor({ client }: { client: Redis }) {\n    this.client = client;\n  }\n\n  async insert({ tableName, record }: { tableName: TABLE_NAMES; record: Record<string, any> }): Promise<void> {\n    const { key, processedRecord } = processRecord(tableName, record);\n\n    try {\n      await this.client.set(key, processedRecord);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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<R>(key);\n      return data || null;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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    do {\n      const [nextCursor, keys] = await this.client.scan(cursor, {\n        match: pattern,\n        count: batchSize,\n      });\n      if (keys.length > 0) {\n        await this.client.del(...keys);\n        totalDeleted += keys.length;\n      }\n      cursor = nextCursor;\n    } while (cursor !== '0');\n    return totalDeleted;\n  }\n\n  async scanKeys(pattern: string, batchSize = 10000): Promise<string[]> {\n    let cursor = '0';\n    let keys: string[] = [];\n    do {\n      const [nextCursor, batch] = await this.client.scan(cursor, {\n        match: pattern,\n        count: batchSize,\n      });\n      keys.push(...batch);\n      cursor = nextCursor;\n    } while (cursor !== '0');\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('UPSTASH', '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","import type { BackgroundTask, BackgroundTaskStatus, TaskFilter, TaskListResult } from '@mastra/core/background-tasks';\nimport { BackgroundTasksStorage, TABLE_BACKGROUND_TASKS } from '@mastra/core/storage';\nimport type { Redis } from '@upstash/redis';\nimport { UpstashDB, resolveUpstashConfig } from '../../db';\nimport type { UpstashDomainConfig } from '../../db';\nimport { getKey, processRecord } from '../utils';\n\nfunction toStorageRecord(task: BackgroundTask): Record<string, any> {\n  return {\n    id: task.id,\n    tool_call_id: task.toolCallId,\n    tool_name: task.toolName,\n    agent_id: task.agentId,\n    thread_id: task.threadId ?? null,\n    resource_id: task.resourceId ?? null,\n    run_id: task.runId,\n    status: task.status,\n    args: task.args,\n    result: task.result ?? null,\n    error: task.error ?? null,\n    suspend_payload: task.suspendPayload ?? null,\n    retry_count: task.retryCount,\n    max_retries: task.maxRetries,\n    timeout_ms: task.timeoutMs,\n    createdAt: task.createdAt.toISOString(),\n    startedAt: task.startedAt?.toISOString() ?? null,\n    suspendedAt: task.suspendedAt?.toISOString() ?? null,\n    completedAt: task.completedAt?.toISOString() ?? null,\n  };\n}\n\nfunction fromStorageRecord(record: Record<string, any>): BackgroundTask {\n  return {\n    id: record.id,\n    status: record.status as BackgroundTaskStatus,\n    toolName: record.tool_name,\n    toolCallId: record.tool_call_id,\n    args: record.args ?? {},\n    agentId: record.agent_id,\n    threadId: record.thread_id ?? undefined,\n    resourceId: record.resource_id ?? undefined,\n    runId: record.run_id ?? '',\n    result: record.result ?? undefined,\n    error: record.error ?? undefined,\n    suspendPayload: record.suspend_payload ?? undefined,\n    retryCount: Number(record.retry_count ?? 0),\n    maxRetries: Number(record.max_retries ?? 0),\n    timeoutMs: Number(record.timeout_ms ?? 300_000),\n    createdAt: new Date(record.createdAt),\n    startedAt: record.startedAt ? new Date(record.startedAt) : undefined,\n    suspendedAt: record.suspendedAt ? new Date(record.suspendedAt) : undefined,\n    completedAt: record.completedAt ? new Date(record.completedAt) : undefined,\n  };\n}\n\nexport class BackgroundTasksUpstash extends BackgroundTasksStorage {\n  private client: Redis;\n  #db: UpstashDB;\n\n  constructor(config: UpstashDomainConfig) {\n    super();\n    const client = resolveUpstashConfig(config);\n    this.client = client;\n    this.#db = new UpstashDB({ client });\n  }\n\n  async dangerouslyClearAll(): Promise<void> {\n    await this.#db.deleteData({ tableName: TABLE_BACKGROUND_TASKS });\n  }\n\n  async createTask(task: BackgroundTask): Promise<void> {\n    const record = toStorageRecord(task);\n    const { key, processedRecord } = processRecord(TABLE_BACKGROUND_TASKS, record);\n    await this.client.set(key, processedRecord);\n  }\n\n  async updateTask(\n    taskId: string,\n    update: Partial<BackgroundTask>,\n    options?: { expectedStatus?: BackgroundTask['status'] },\n  ): Promise<boolean> {\n    const patch: Record<string, unknown> = {};\n    if ('status' in update) patch.status = update.status;\n    if ('result' in update) patch.result = update.result ?? null;\n    if ('error' in update) patch.error = update.error ?? null;\n    if ('suspendPayload' in update) patch.suspend_payload = update.suspendPayload ?? null;\n    if ('retryCount' in update) patch.retry_count = update.retryCount;\n    if ('startedAt' in update) patch.startedAt = update.startedAt?.toISOString() ?? null;\n    if ('suspendedAt' in update) patch.suspendedAt = update.suspendedAt?.toISOString() ?? null;\n    if ('completedAt' in update) patch.completedAt = update.completedAt?.toISOString() ?? null;\n    if (Object.keys(patch).length === 0) return false;\n\n    const key = getKey(TABLE_BACKGROUND_TASKS, { id: taskId });\n    const result = await this.client.eval(\n      `\n        local existing = redis.call('GET', KEYS[1])\n        if not existing then return 0 end\n        local record = cjson.decode(existing)\n        if ARGV[1] ~= '' and record.status ~= ARGV[1] then return 0 end\n        local patch = cjson.decode(ARGV[2])\n        for field, value in pairs(patch) do record[field] = value end\n        redis.call('SET', KEYS[1], cjson.encode(record))\n        return 1\n      `,\n      [key],\n      [options?.expectedStatus ?? '', JSON.stringify(patch)],\n    );\n    return Number(result) === 1;\n  }\n\n  async getTask(taskId: string): Promise<BackgroundTask | null> {\n    const key = getKey(TABLE_BACKGROUND_TASKS, { id: taskId });\n    const data = await this.client.get<Record<string, any>>(key);\n    if (!data) return null;\n    return fromStorageRecord(data);\n  }\n\n  async listTasks(filter: TaskFilter): Promise<TaskListResult> {\n    // Scan all background task keys\n    const keys = await this.#db.scanKeys(`${TABLE_BACKGROUND_TASKS}:*`);\n    if (keys.length === 0) return { tasks: [], total: 0 };\n\n    // Fetch all records\n    const pipeline = this.client.pipeline();\n    for (const key of keys) {\n      pipeline.get(key);\n    }\n    const results = await pipeline.exec<Record<string, any>[]>();\n\n    let tasks = results.filter(Boolean).map(r => fromStorageRecord(r));\n\n    // Apply filters\n    if (filter.status) {\n      const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];\n      tasks = tasks.filter(t => statuses.includes(t.status));\n    }\n    if (filter.agentId) {\n      tasks = tasks.filter(t => t.agentId === filter.agentId);\n    }\n    if (filter.threadId) {\n      tasks = tasks.filter(t => t.threadId === filter.threadId);\n    }\n    if (filter.resourceId) {\n      tasks = tasks.filter(t => t.resourceId === filter.resourceId);\n    }\n    if (filter.runId) {\n      tasks = tasks.filter(t => t.runId === filter.runId);\n    }\n    if (filter.toolName) {\n      tasks = tasks.filter(t => t.toolName === filter.toolName);\n    }\n    if (filter.toolCallId) {\n      tasks = tasks.filter(t => t.toolCallId === filter.toolCallId);\n    }\n    // Date range filtering\n    const dateCol = filter.dateFilterBy ?? 'createdAt';\n    if (filter.fromDate) {\n      tasks = tasks.filter(t => {\n        const val = t[dateCol];\n        return val != null && val >= filter.fromDate!;\n      });\n    }\n    if (filter.toDate) {\n      tasks = tasks.filter(t => {\n        const val = t[dateCol];\n        return val != null && val < filter.toDate!;\n      });\n    }\n\n    // Sort\n    const orderBy = filter.orderBy ?? 'createdAt';\n    const direction = filter.orderDirection ?? 'asc';\n    tasks.sort((a, b) => {\n      const aVal = a[orderBy]?.getTime() ?? 0;\n      const bVal = b[orderBy]?.getTime() ?? 0;\n      return direction === 'asc' ? aVal - bVal : bVal - aVal;\n    });\n\n    // Capture total before pagination\n    const total = tasks.length;\n\n    // Pagination\n    if (filter.page != null && filter.perPage != null) {\n      const start = filter.page * filter.perPage;\n      tasks = tasks.slice(start, start + filter.perPage);\n    } else if (filter.perPage != null) {\n      tasks = tasks.slice(0, filter.perPage);\n    }\n\n    return { tasks, total };\n  }\n\n  async deleteTask(taskId: string): Promise<void> {\n    const key = getKey(TABLE_BACKGROUND_TASKS, { id: taskId });\n    await this.client.del(key);\n  }\n\n  async deleteTasks(filter: TaskFilter): Promise<void> {\n    // Get tasks matching filter, then delete by key\n    const { tasks } = await this.listTasks(filter);\n    if (tasks.length === 0) return;\n\n    const keys = tasks.map(t => getKey(TABLE_BACKGROUND_TASKS, { id: t.id }));\n    if (keys.length > 0) {\n      await this.client.del(...keys);\n    }\n  }\n\n  async getRunningCount(): Promise<number> {\n    const { total } = await this.listTasks({ status: 'running' });\n    return total;\n  }\n\n  async getRunningCountByAgent(agentId: string): Promise<number> {\n    const { total } = await this.listTasks({ status: 'running', agentId });\n    return total;\n  }\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  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';\nimport type { Redis } from '@upstash/redis';\nimport { UpstashDB, resolveUpstashConfig } from '../../db';\nimport type { UpstashDomainConfig } from '../../db';\nimport { getKey, processRecord } from '../utils';\n\nfunction getThreadMessagesKey(threadId: string): string {\n  return `thread:${threadId}:messages`;\n}\n\nfunction getMessageKey(threadId: string, messageId: string): string {\n  const key = getKey(TABLE_MESSAGES, { threadId, id: messageId });\n  return key;\n}\n\n// Index key for fast message ID -> threadId lookup (backwards compatible)\nfunction getMessageIndexKey(messageId: string): string {\n  return `msg-idx:${messageId}`;\n}\n\nexport class StoreMemoryUpstash extends MemoryStorage {\n  override readonly supportsPartialThreadUpdate = true;\n  private client: Redis;\n  #db: UpstashDB;\n  constructor(config: UpstashDomainConfig) {\n    super();\n    const client = resolveUpstashConfig(config);\n    this.client = client;\n    this.#db = new UpstashDB({ client });\n  }\n\n  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  }\n\n  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)) return null;\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('UPSTASH', '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 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      // Validate pagination input before normalization\n      // This ensures page === 0 when perPageInput === false\n      this.validatePaginationInput(page, perPageInput ?? 100);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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    // Validate metadata keys to prevent prototype pollution and ensure safe key patterns\n    try {\n      this.validateMetadataKeys(filter?.metadata);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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      // Return early if no keys found to avoid \"Pipeline is empty\" error\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 pipeline = this.client.pipeline();\n      keys.forEach(key => pipeline.get(key));\n      const results = await pipeline.exec();\n\n      for (let i = 0; i < results.length; i++) {\n        const thread = results[i] as StorageThreadType | null;\n        if (!thread) continue;\n\n        // Apply resourceId filter if provided\n        if (filter?.resourceId && thread.resourceId !== filter.resourceId) {\n          continue;\n        }\n\n        // Apply metadata filters if provided (AND logic)\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]) => threadMetadata?.[key] === value);\n          if (!matches) continue;\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      // Apply sorting with parameters\n      const sortedThreads = this.sortThreads(allThreads, field, direction);\n\n      const total = sortedThreads.length;\n      // When perPage is false (get all), ignore page offset\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('UPSTASH', '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  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('UPSTASH', '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  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('UPSTASH', '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 now = new Date();\n    const updatedThread = {\n      ...thread,\n      title: title ?? thread.title,\n      metadata: {\n        ...thread.metadata,\n        ...metadata,\n      },\n      updatedAt: now,\n    };\n\n    try {\n      await this.saveThread({ thread: updatedThread });\n      return updatedThread;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  async deleteThread({ threadId }: { threadId: string }): Promise<void> {\n    // Delete thread metadata and sorted set\n    const threadKey = getKey(TABLE_THREADS, { id: threadId });\n    const threadMessagesKey = getThreadMessagesKey(threadId);\n    try {\n      const messageIds: string[] = await this.client.zrange(threadMessagesKey, 0, -1);\n\n      const pipeline = this.client.pipeline();\n      pipeline.del(threadKey);\n      pipeline.del(threadMessagesKey);\n\n      for (let i = 0; i < messageIds.length; i++) {\n        const messageId = messageIds[i];\n        const messageKey = getMessageKey(threadId, messageId as string);\n        pipeline.del(messageKey);\n      }\n\n      await pipeline.exec();\n\n      // Bulk delete all message keys for this thread if any remain\n      await this.#db.scanAndDelete(getMessageKey(threadId, '*'));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  async saveMessages(args: { messages: MastraDBMessage[] }): Promise<{ messages: MastraDBMessage[] }> {\n    const { messages } = args;\n    if (messages.length === 0) return { messages: [] };\n\n    try {\n      for (const message of messages) {\n        if (!message.threadId) {\n          throw new Error('Thread ID is required');\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      }\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', 'SAVE_MESSAGES', 'INVALID_ARGS'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n        },\n        error,\n      );\n    }\n\n    // Add an index to each message to maintain order\n    const messagesWithIndex = messages.map((message, index) => {\n      return {\n        ...message,\n        _index: index,\n      };\n    });\n\n    try {\n      const batchSize = 1000;\n      const targetThreadIds = new Set(messagesWithIndex.map(message => message.threadId!));\n      const existingThreadIds: (string | null)[] = [];\n      const touchedThreadIds = new Set<string>(targetThreadIds);\n\n      // Read index entries up front so all touched threads can be validated/loaded before writes.\n      for (let i = 0; i < messagesWithIndex.length; i += batchSize) {\n        const batch = messagesWithIndex.slice(i, i + batchSize);\n        const indexLookupPipeline = this.client.pipeline();\n\n        batch.forEach(message => {\n          indexLookupPipeline.get(getMessageIndexKey(message.id));\n        });\n        const batchExistingThreadIds = (await indexLookupPipeline.exec()) as (string | null)[];\n        existingThreadIds.push(...batchExistingThreadIds);\n\n        batchExistingThreadIds.forEach(existingThreadId => {\n          if (existingThreadId) {\n            touchedThreadIds.add(existingThreadId);\n          }\n        });\n      }\n\n      const touchedThreadIdList = Array.from(touchedThreadIds);\n      const threadLookupPipeline = this.client.pipeline();\n      touchedThreadIdList.forEach(touchedThreadId => {\n        threadLookupPipeline.get(getKey(TABLE_THREADS, { id: touchedThreadId }));\n      });\n      const threadLookupResults = (await threadLookupPipeline.exec()) as (StorageThreadType | null)[];\n      const threadRecordsById = new Map<string, StorageThreadType>();\n\n      touchedThreadIdList.forEach((touchedThreadId, index) => {\n        const threadRecord = threadLookupResults[index];\n        if (threadRecord) {\n          threadRecordsById.set(touchedThreadId, threadRecord);\n        }\n      });\n\n      for (const targetThreadId of targetThreadIds) {\n        if (!threadRecordsById.has(targetThreadId)) {\n          throw new MastraError(\n            {\n              id: createStorageErrorId('UPSTASH', 'SAVE_MESSAGES', 'INVALID_ARGS'),\n              domain: ErrorDomain.STORAGE,\n              category: ErrorCategory.USER,\n            },\n            new Error(`Thread ${targetThreadId} not found`),\n          );\n        }\n      }\n\n      for (let i = 0; i < messagesWithIndex.length; i += batchSize) {\n        const batch = messagesWithIndex.slice(i, i + batchSize);\n        const pipeline = this.client.pipeline();\n        const batchTouchedThreadIds = new Set<string>();\n        const batchExistingThreadIds = existingThreadIds.slice(i, i + batch.length);\n\n        for (const [batchIndex, message] of batch.entries()) {\n          const key = getMessageKey(message.threadId!, message.id);\n          const createdAtScore = new Date(message.createdAt).getTime();\n          const score = message._index !== undefined ? message._index : createdAtScore;\n          batchTouchedThreadIds.add(message.threadId!);\n\n          // Check if this message id exists in another thread (index lookup, no scan)\n          const existingThreadId = batchExistingThreadIds[batchIndex];\n          if (existingThreadId && existingThreadId !== message.threadId) {\n            pipeline.del(getMessageKey(existingThreadId, message.id));\n            pipeline.zrem(getThreadMessagesKey(existingThreadId), message.id);\n            batchTouchedThreadIds.add(existingThreadId);\n          }\n\n          // Store the message data\n          pipeline.set(key, message);\n\n          // Store the message ID -> threadId index for fast lookups\n          pipeline.set(getMessageIndexKey(message.id), message.threadId!);\n\n          // Add to sorted set for this thread\n          pipeline.zadd(getThreadMessagesKey(message.threadId!), {\n            score,\n            member: message.id,\n          });\n        }\n\n        const now = new Date();\n        for (const touchedThreadId of batchTouchedThreadIds) {\n          const existingThread = threadRecordsById.get(touchedThreadId);\n          if (!existingThread) {\n            continue;\n          }\n          const updatedThread = {\n            ...existingThread,\n            updatedAt: now,\n          };\n          const threadKey = getKey(TABLE_THREADS, { id: touchedThreadId });\n          pipeline.set(threadKey, processRecord(TABLE_THREADS, updatedThread).processedRecord);\n          threadRecordsById.set(touchedThreadId, updatedThread);\n        }\n\n        await pipeline.exec();\n      }\n\n      const list = new MessageList().add(messages as any, 'memory');\n      return { messages: list.get.all.db() };\n    } catch (error) {\n      if (error instanceof MastraError) {\n        throw error;\n      }\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', 'SAVE_MESSAGES', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            threadIds: Array.from(new Set(messages.map(message => message.threadId).filter(Boolean))).join(','),\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * Lookup threadId for a message - tries index first (O(1)), falls back to scan (backwards compatible)\n   */\n  private async _getThreadIdForMessage(messageId: string): Promise<string | null> {\n    // Try the index first (fast path for new messages)\n    const indexedThreadId = await this.client.get<string>(getMessageIndexKey(messageId));\n    if (indexedThreadId) {\n      return indexedThreadId;\n    }\n\n    // Fall back to scan for backwards compatibility (old messages without index)\n    const existingKeyPattern = getMessageKey('*', messageId);\n    const keys = await this.#db.scanKeys(existingKeyPattern);\n    if (keys.length === 0) return null;\n\n    // Get the message to find its threadId\n    const messageData = await this.client.get<MastraDBMessage>(keys[0] as string);\n    if (!messageData) return null;\n\n    // Backfill the index for future lookups\n    if (messageData.threadId) {\n      await this.client.set(getMessageIndexKey(messageId), messageData.threadId);\n    }\n\n    return messageData.threadId || null;\n  }\n\n  private _sortMessages(messages: MastraDBMessage[], field: string, direction: string): MastraDBMessage[] {\n    return messages.sort((a, b) => {\n      const getVal = (msg: MastraDBMessage): number => {\n        if (field === 'createdAt') {\n          return new Date(msg.createdAt).getTime();\n        }\n        const value = (msg as Record<string, unknown>)[field];\n        if (typeof value === 'number') return value;\n        if (value instanceof Date) return value.getTime();\n        return 0;\n      };\n      const aValue = getVal(a);\n      const bValue = getVal(b);\n      return direction === 'ASC' ? aValue - bValue : bValue - aValue;\n    });\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) return [];\n\n    const messageIds = new Set<string>();\n    const messageIdToThreadIds: Record<string, string> = {};\n\n    for (const item of include) {\n      // Step 1: Find the threadId for this message (index first, then scan)\n      const itemThreadId = await this._getThreadIdForMessage(item.id);\n      if (!itemThreadId) continue;\n\n      const itemThreadMessagesKey = getThreadMessagesKey(itemThreadId);\n\n      if (resourceId !== undefined) {\n        const threadMessageIds = (await this.client.zrange(itemThreadMessagesKey, 0, -1)) as string[];\n        const threadPipeline = this.client.pipeline();\n        threadMessageIds.forEach(id => threadPipeline.get(getMessageKey(itemThreadId, id)));\n        const threadMessages = (await threadPipeline.exec())\n          .filter((message): message is MastraDBMessage => message !== null)\n          .filter(message => message.resourceId === resourceId);\n        const targetIndex = threadMessages.findIndex(message => message.id === item.id);\n        if (targetIndex === -1) continue;\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\n      // Get the rank of this message in the sorted set\n      const rank = await this.client.zrank(itemThreadMessagesKey, item.id);\n      if (rank === null) continue;\n\n      // Get previous messages if requested\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 as string);\n          messageIdToThreadIds[id as string] = itemThreadId;\n        });\n      }\n\n      // Get next messages if requested\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 as string);\n          messageIdToThreadIds[id as string] = itemThreadId;\n        });\n      }\n    }\n\n    if (messageIds.size === 0) return [];\n\n    const pipeline = this.client.pipeline();\n    Array.from(messageIds).forEach(id => {\n      const tId = messageIdToThreadIds[id]!;\n      pipeline.get(getMessageKey(tId, id as string));\n    });\n    const results = await pipeline.exec();\n    const includedMessages = results.filter(result => result !== null) 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) return { messages: [] };\n\n    try {\n      const rawMessages: (MastraDBMessage & { _index?: number })[] = [];\n\n      // Try to get threadIds from index first (fast path)\n      const indexPipeline = this.client.pipeline();\n      messageIds.forEach(id => indexPipeline.get(getMessageIndexKey(id)));\n      const indexResults = await indexPipeline.exec();\n\n      const indexedIds: { messageId: string; threadId: string }[] = [];\n      const unindexedIds: string[] = [];\n\n      messageIds.forEach((id, i) => {\n        const threadId = indexResults[i] as string | null;\n        if (threadId) {\n          indexedIds.push({ messageId: id, threadId });\n        } else {\n          unindexedIds.push(id);\n        }\n      });\n\n      // Fetch indexed messages directly (O(1) per message)\n      if (indexedIds.length > 0) {\n        const messagePipeline = this.client.pipeline();\n        indexedIds.forEach(({ messageId, threadId }) => messagePipeline.get(getMessageKey(threadId, messageId)));\n        const messageResults = await messagePipeline.exec();\n        rawMessages.push(...(messageResults.filter(msg => msg !== null) as (MastraDBMessage & { _index?: number })[]));\n      }\n\n      // Fall back to scan for unindexed messages (backwards compatibility)\n      if (unindexedIds.length > 0) {\n        const threadKeys = await this.client.keys('thread:*');\n\n        const result = await Promise.all(\n          threadKeys.map(threadKey => {\n            const threadId = threadKey.split(':')[1];\n            if (!threadId) throw new Error(`Failed to parse thread ID from thread key \"${threadKey}\"`);\n            return this.client.mget<(MastraDBMessage & { _index?: number })[]>(\n              unindexedIds.map(id => getMessageKey(threadId, id)),\n            );\n          }),\n        );\n\n        const foundMessages = result.flat(1).filter(msg => !!msg) as (MastraDBMessage & { _index?: number })[];\n        rawMessages.push(...foundMessages);\n\n        // Backfill index for found messages\n        if (foundMessages.length > 0) {\n          const backfillPipeline = this.client.pipeline();\n          foundMessages.forEach(msg => {\n            if (msg.threadId) {\n              backfillPipeline.set(getMessageIndexKey(msg.id), msg.threadId);\n            }\n          });\n          await backfillPipeline.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('UPSTASH', '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    // Normalize threadId to array\n    const threadIds = Array.isArray(threadId) ? threadId : [threadId];\n\n    if (threadIds.length === 0 || threadIds.some(id => !id.trim())) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', 'LIST_MESSAGES', 'INVALID_THREAD_ID'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\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    // When perPage is false (get all), ignore page offset\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('UPSTASH', '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      // Determine sort field and direction, default to ASC (oldest first)\n      const { field, direction } = this.parseOrderBy(orderBy, 'ASC');\n\n      // When perPage is 0 with no includes, there's nothing to return.\n      if (perPage === 0 && (!include || include.length === 0)) {\n        return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };\n      }\n\n      // Get included messages with context if specified\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      // When perPage is 0, we only need included messages — skip thread load entirely\n      if (perPage === 0 && include && include.length > 0) {\n        const list = new MessageList().add(includedMessages, 'memory');\n        return {\n          messages: this._sortMessages(list.get.all.db(), field, direction),\n          total: 0,\n          page,\n          perPage: perPageForResponse,\n          hasMore: false,\n        };\n      }\n\n      // Get all message IDs from all thread sorted sets\n      const allMessageIdsWithThreads: { threadId: string; messageId: string }[] = [];\n      for (const tid of threadIds) {\n        const threadMessagesKey = getThreadMessagesKey(tid);\n        const messageIds = await this.client.zrange(threadMessagesKey, 0, -1);\n        for (const mid of messageIds) {\n          allMessageIdsWithThreads.push({ threadId: tid, messageId: mid as string });\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      // Use pipeline to fetch all messages efficiently\n      const pipeline = this.client.pipeline();\n      allMessageIdsWithThreads.forEach(({ threadId: tid, messageId }) => pipeline.get(getMessageKey(tid, messageId)));\n      const results = await pipeline.exec();\n\n      // Process messages and apply filters\n      let messagesData = results\n        .filter((msg): msg is MastraDBMessage & { _index?: number } => msg !== null)\n        .map(this.parseStoredMessage);\n\n      // Filter by resourceId if provided\n      if (resourceId) {\n        messagesData = messagesData.filter(msg => msg.resourceId === resourceId);\n      }\n\n      // Apply date filters if provided\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      // Always sort messages by the sort field/direction before pagination\n      // This ensures consistent ordering whether orderBy is explicit or uses the default (createdAt ASC)\n      messagesData = this._sortMessages(messagesData, field, direction);\n\n      const total = messagesData.length;\n\n      // Apply pagination\n      const start = offset;\n      const end = perPageInput === false ? total : start + perPage;\n      const paginatedMessages = messagesData.slice(start, end);\n\n      // Combine paginated messages with included messages, deduplicating\n      const messageIds = new Set<string>();\n      const allMessages: MastraDBMessage[] = [];\n\n      // Add paginated messages first\n      for (const msg of paginatedMessages) {\n        if (!messageIds.has(msg.id)) {\n          allMessages.push(msg);\n          messageIds.add(msg.id);\n        }\n      }\n\n      // Add included messages (with context), avoiding duplicates\n      for (const msg of includedMessages) {\n        if (!messageIds.has(msg.id)) {\n          allMessages.push(msg);\n          messageIds.add(msg.id);\n        }\n      }\n\n      // Use MessageList for proper deduplication and format conversion\n      const list = new MessageList().add(allMessages, 'memory');\n      let finalMessages = list.get.all.db();\n\n      // Sort all messages (paginated + included) for final output - must be done AFTER MessageList\n      // because MessageList.get.all.db() sorts by createdAt ASC internally\n      // Always sort by createdAt (or specified field) to ensure consistent chronological ordering\n      // This is critical when `include` parameter brings in messages from semantic recall\n      finalMessages = this._sortMessages(finalMessages, field, direction);\n\n      const threadIdSet = new Set(threadIds);\n      const returnedThreadMessageIds = new Set(\n        finalMessages\n          .filter(message => message.threadId && threadIdSet.has(message.threadId))\n          .map(message => message.id),\n      );\n      const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;\n      const hasMore = metadataFilter\n        ? perPageInput !== false && offset + paginatedMessages.length < total\n        : perPageInput !== false && !allThreadMessagesReturned && offset + perPage < 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('UPSTASH', '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  async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {\n    try {\n      const key = `${TABLE_RESOURCES}:${resourceId}`;\n      const data = await this.client.get<StorageResourceType>(key);\n\n      if (!data) {\n        return null;\n      }\n\n      return {\n        ...data,\n        createdAt: new Date(data.createdAt),\n        updatedAt: new Date(data.updatedAt),\n        // Ensure workingMemory is always returned as a string, regardless of automatic parsing\n        workingMemory: typeof data.workingMemory === 'object' ? JSON.stringify(data.workingMemory) : data.workingMemory,\n        metadata: typeof data.metadata === 'string' ? JSON.parse(data.metadata) : data.metadata,\n      };\n    } catch (error) {\n      this.logger.error('Error getting resource by ID:', error);\n      throw error;\n    }\n  }\n\n  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, serializedResource);\n\n      return resource;\n    } catch (error) {\n      this.logger.error('Error saving resource:', error);\n      throw error;\n    }\n  }\n\n  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        // Create new resource if it doesn't exist\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  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\n    if (messages.length === 0) {\n      return [];\n    }\n\n    try {\n      // Get all message IDs to update\n      const messageIds = messages.map(m => m.id);\n      const updatesById = new Map(messages.map(message => [message.id, message]));\n\n      // Find all existing messages — try index first, fall back to scan\n      const existingMessages: MastraDBMessage[] = [];\n      const messageIdToKey: Record<string, string> = {};\n      const backfillIndexValues: Record<string, string> = {};\n\n      const indexPipeline = this.client.pipeline();\n      messageIds.forEach(messageId => indexPipeline.get(getMessageIndexKey(messageId)));\n      const indexResults = (await indexPipeline.exec()) as (string | null)[];\n\n      const indexedLookups: { messageId: string; threadId: string }[] = [];\n      const fallbackMessageIds: string[] = [];\n\n      messageIds.forEach((messageId, index) => {\n        const indexedThreadId = indexResults[index];\n        if (indexedThreadId) {\n          indexedLookups.push({ messageId, threadId: indexedThreadId });\n        } else {\n          fallbackMessageIds.push(messageId);\n        }\n      });\n\n      if (indexedLookups.length > 0) {\n        const messagePipeline = this.client.pipeline();\n        indexedLookups.forEach(({ messageId, threadId }) => {\n          messagePipeline.get(getMessageKey(threadId, messageId));\n        });\n        const indexedMessages = (await messagePipeline.exec()) as (MastraDBMessage | null)[];\n\n        indexedLookups.forEach(({ messageId, threadId }, index) => {\n          const key = getMessageKey(threadId, messageId);\n          const message = indexedMessages[index];\n          if (message && message.id === messageId) {\n            existingMessages.push(message);\n            messageIdToKey[messageId] = key;\n          } else {\n            fallbackMessageIds.push(messageId);\n          }\n        });\n      }\n\n      for (const messageId of fallbackMessageIds) {\n        // Fall back to scan for backwards compatibility (old messages without index)\n        const pattern = getMessageKey('*', messageId);\n        const keys = await this.#db.scanKeys(pattern);\n\n        for (const key of keys) {\n          const message = await this.client.get<MastraDBMessage>(key);\n          if (message && message.id === messageId) {\n            existingMessages.push(message);\n            messageIdToKey[messageId] = key;\n            // Backfill the index for future lookups\n            if (message.threadId) {\n              backfillIndexValues[messageId] = message.threadId;\n            }\n            break;\n          }\n        }\n      }\n\n      if (Object.keys(backfillIndexValues).length > 0) {\n        const backfillPipeline = this.client.pipeline();\n        for (const [messageId, threadId] of Object.entries(backfillIndexValues)) {\n          backfillPipeline.set(getMessageIndexKey(messageId), threadId);\n        }\n        await backfillPipeline.exec();\n      }\n\n      if (existingMessages.length === 0) {\n        return [];\n      }\n\n      const threadIdsToUpdate = new Set<string>();\n      const destinationThreadIds = new Set<string>();\n\n      for (const existingMessage of existingMessages) {\n        const updatePayload = updatesById.get(existingMessage.id);\n        if (!updatePayload) continue;\n\n        const { id: _id, ...fieldsToUpdate } = updatePayload;\n        if (Object.keys(fieldsToUpdate).length === 0) continue;\n\n        threadIdsToUpdate.add(existingMessage.threadId!);\n        if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {\n          threadIdsToUpdate.add(updatePayload.threadId);\n          destinationThreadIds.add(updatePayload.threadId);\n        }\n      }\n\n      const threadRecordsById = new Map<string, StorageThreadType>();\n      if (threadIdsToUpdate.size > 0) {\n        const threadIdList = Array.from(threadIdsToUpdate);\n        const threadLookupPipeline = this.client.pipeline();\n\n        threadIdList.forEach(threadId => {\n          threadLookupPipeline.get(getKey(TABLE_THREADS, { id: threadId }));\n        });\n        const threadLookupResults = (await threadLookupPipeline.exec()) as (StorageThreadType | null)[];\n\n        threadIdList.forEach((threadId, index) => {\n          const threadRecord = threadLookupResults[index];\n          if (threadRecord) {\n            threadRecordsById.set(threadId, threadRecord);\n          }\n        });\n      }\n\n      for (const destinationThreadId of destinationThreadIds) {\n        if (!threadRecordsById.has(destinationThreadId)) {\n          throw new MastraError(\n            {\n              id: createStorageErrorId('UPSTASH', 'UPDATE_MESSAGES', 'INVALID_ARGS'),\n              domain: ErrorDomain.STORAGE,\n              category: ErrorCategory.USER,\n            },\n            new Error(`Thread ${destinationThreadId} not found`),\n          );\n        }\n      }\n\n      const pipeline = this.client.pipeline();\n\n      // Process each existing message for updates\n      for (const existingMessage of existingMessages) {\n        const updatePayload = updatesById.get(existingMessage.id);\n        if (!updatePayload) continue;\n\n        const { id, ...fieldsToUpdate } = updatePayload;\n        if (Object.keys(fieldsToUpdate).length === 0) continue;\n\n        // Create updated message object\n        const updatedMessage = { ...existingMessage };\n\n        // Special handling for the content field to merge instead of overwrite\n        if (fieldsToUpdate.content) {\n          const existingContent = existingMessage.content as MastraMessageContentV2;\n          const newContent = {\n            ...existingContent,\n            ...fieldsToUpdate.content,\n            // Deep merge metadata if it exists on both\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        // Update other fields\n        for (const key in fieldsToUpdate) {\n          if (Object.prototype.hasOwnProperty.call(fieldsToUpdate, key) && key !== 'content') {\n            (updatedMessage as any)[key] = fieldsToUpdate[key as keyof typeof fieldsToUpdate];\n          }\n        }\n\n        // Update the message in Redis\n        const key = messageIdToKey[id];\n        if (key) {\n          // If the message is being moved to a different thread, we need to handle the key change\n          if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {\n            const newThreadId = updatedMessage.threadId!;\n\n            // Remove from old thread's sorted set\n            const oldThreadMessagesKey = getThreadMessagesKey(existingMessage.threadId!);\n            pipeline.zrem(oldThreadMessagesKey, id);\n\n            // Delete the old message key\n            pipeline.del(key);\n\n            // Create new message key with new threadId\n            const newKey = getMessageKey(newThreadId, id);\n            pipeline.set(newKey, updatedMessage);\n            pipeline.set(getMessageIndexKey(id), newThreadId);\n            messageIdToKey[id] = newKey;\n\n            // Add to new thread's sorted set\n            const newThreadMessagesKey = getThreadMessagesKey(newThreadId);\n            const score =\n              (updatedMessage as any)._index !== undefined\n                ? (updatedMessage as any)._index\n                : new Date(updatedMessage.createdAt).getTime();\n            pipeline.zadd(newThreadMessagesKey, { score, member: id });\n          } else {\n            // No thread change, just update the existing key\n            pipeline.set(key, updatedMessage);\n          }\n        }\n      }\n\n      // Update thread timestamps\n      const now = new Date();\n      for (const threadId of threadIdsToUpdate) {\n        if (threadId) {\n          const existingThread = threadRecordsById.get(threadId);\n          if (existingThread) {\n            const updatedThread = {\n              ...existingThread,\n              updatedAt: now,\n            };\n            const threadKey = getKey(TABLE_THREADS, { id: threadId });\n            pipeline.set(threadKey, processRecord(TABLE_THREADS, updatedThread).processedRecord);\n            threadRecordsById.set(threadId, updatedThread);\n          }\n        }\n      }\n\n      // Execute all updates\n      await pipeline.exec();\n\n      // Return the updated messages\n      const updatedMessages: MastraDBMessage[] = [];\n      for (const messageId of messageIds) {\n        const key = messageIdToKey[messageId];\n        if (key) {\n          const updatedMessage = await this.client.get<MastraDBMessage>(key);\n          if (updatedMessage) {\n            updatedMessages.push(updatedMessage);\n          }\n        }\n      }\n\n      return updatedMessages;\n    } catch (error) {\n      if (error instanceof MastraError) {\n        throw error;\n      }\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  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\n      // Try index first for each message (fast path)\n      const indexPipeline = this.client.pipeline();\n      messageIds.forEach(id => indexPipeline.get(getMessageIndexKey(id)));\n      const indexResults = await indexPipeline.exec();\n\n      const indexedMessages: { messageId: string; threadId: string }[] = [];\n      const unindexedMessageIds: string[] = [];\n\n      messageIds.forEach((id, i) => {\n        const threadId = indexResults[i] as string | null;\n        if (threadId) {\n          indexedMessages.push({ messageId: id, threadId });\n        } else {\n          unindexedMessageIds.push(id);\n        }\n      });\n\n      // Process indexed messages (fast path)\n      for (const { messageId, threadId } of indexedMessages) {\n        messageKeys.push(getMessageKey(threadId, messageId));\n        foundMessageIds.push(messageId);\n        threadIds.add(threadId);\n      }\n\n      // Fall back to scan for unindexed messages (backwards compatibility)\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 message = await this.client.get<MastraDBMessage>(key);\n          if (message && message.id === messageId) {\n            messageKeys.push(key);\n            foundMessageIds.push(messageId);\n            if (message.threadId) {\n              threadIds.add(message.threadId);\n            }\n            break;\n          }\n        }\n      }\n\n      if (messageKeys.length === 0) {\n        // none of the message ids existed\n        return;\n      }\n\n      const pipeline = this.client.pipeline();\n\n      // Delete all messages\n      for (const key of messageKeys) {\n        pipeline.del(key);\n      }\n\n      // Delete all message index entries\n      for (const messageId of foundMessageIds) {\n        pipeline.del(getMessageIndexKey(messageId));\n      }\n\n      // Update thread timestamps\n      if (threadIds.size > 0) {\n        for (const threadId of threadIds) {\n          const threadKey = getKey(TABLE_THREADS, { id: threadId });\n          const thread = await this.client.get<StorageThreadType>(threadKey);\n          if (thread) {\n            const updatedThread = {\n              ...thread,\n              updatedAt: new Date(),\n            };\n            pipeline.set(threadKey, processRecord(TABLE_THREADS, updatedThread).processedRecord);\n          }\n        }\n      }\n\n      // Execute all operations\n      await pipeline.exec();\n\n      // TODO: Delete from vector store if semantic recall is enabled\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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\n      if (direction === 'ASC') {\n        return aValue - bValue;\n      } else {\n        return bValue - aValue;\n      }\n    });\n  }\n\n  async cloneThread(args: StorageCloneThreadInput): Promise<StorageCloneThreadOutput> {\n    const { sourceThreadId, newThreadId: providedThreadId, resourceId, title, metadata, options } = args;\n\n    // Get the source thread\n    const sourceThread = await this.getThreadById({ threadId: sourceThreadId });\n    if (!sourceThread) {\n      throw new MastraError({\n        id: createStorageErrorId('UPSTASH', '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    // Use provided ID or generate a new one\n    const newThreadId = providedThreadId || crypto.randomUUID();\n\n    // Check if the new thread ID already exists\n    const existingThread = await this.getThreadById({ threadId: newThreadId });\n    if (existingThread) {\n      throw new MastraError({\n        id: createStorageErrorId('UPSTASH', '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      // Get all message IDs from the source thread's sorted set\n      const threadMessagesKey = getThreadMessagesKey(sourceThreadId);\n      const messageIds = await this.client.zrange(threadMessagesKey, 0, -1);\n\n      // Fetch all source messages\n      const pipeline = this.client.pipeline();\n      for (const mid of messageIds) {\n        pipeline.get(getMessageKey(sourceThreadId, mid as string));\n      }\n      const results = await pipeline.exec();\n\n      // Parse and filter messages\n      let sourceMessages = results\n        .filter((msg): msg is MastraDBMessage & { _index?: number } => msg !== null)\n        .map(msg => ({\n          ...msg,\n          createdAt: new Date(msg.createdAt),\n        }));\n\n      // Apply date filters\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      // Apply message ID filter\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      // Sort by createdAt ASC\n      sourceMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());\n\n      // Apply message limit (from most recent)\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\n      // Determine the last message ID for clone metadata\n      const lastMessageId = sourceMessages.length > 0 ? sourceMessages[sourceMessages.length - 1]!.id : undefined;\n\n      // Create clone metadata\n      const cloneMetadata: ThreadCloneMetadata = {\n        sourceThreadId,\n        clonedAt: now,\n        ...(lastMessageId && { lastMessageId }),\n      };\n\n      // Create the new thread\n      const newThread: StorageThreadType = {\n        id: newThreadId,\n        resourceId: resourceId || sourceThread.resourceId,\n        title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : ''),\n        metadata: {\n          ...metadata,\n          clone: cloneMetadata,\n        },\n        createdAt: now,\n        updatedAt: now,\n      };\n\n      // Use pipeline for all writes\n      const writePipeline = this.client.pipeline();\n\n      // Save the new thread\n      const threadKey = getKey(TABLE_THREADS, { id: newThreadId });\n      writePipeline.set(threadKey, processRecord(TABLE_THREADS, newThread).processedRecord);\n\n      // Clone messages with new IDs\n      const clonedMessages: MastraDBMessage[] = [];\n      const messageIdMap: Record<string, string> = {};\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        messageIdMap[sourceMsg.id] = newMessageId;\n        const { _index, ...restMsg } = sourceMsg as MastraDBMessage & { _index?: number };\n\n        const newMessage: MastraDBMessage = {\n          ...restMsg,\n          id: newMessageId,\n          threadId: newThreadId,\n          resourceId: targetResourceId,\n        };\n\n        // Store the message data\n        const messageKey = getMessageKey(newThreadId, newMessageId);\n        writePipeline.set(messageKey, newMessage);\n\n        // Store the message ID -> threadId index for fast lookups\n        writePipeline.set(getMessageIndexKey(newMessageId), newThreadId);\n\n        // Add to sorted set for this thread (use index for ordering)\n        writePipeline.zadd(newThreadMessagesKey, {\n          score: i,\n          member: newMessageId,\n        });\n\n        clonedMessages.push(newMessage);\n      }\n\n      // Execute all writes\n      await writePipeline.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('UPSTASH', 'CLONE_THREAD', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { sourceThreadId, newThreadId },\n        },\n        error,\n      );\n    }\n  }\n}\n","import { 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 as coreTransformScoreRow,\n  createStorageErrorId,\n} from '@mastra/core/storage';\nimport type { PaginationInfo, StoragePagination, ScoreTenancyFilters } from '@mastra/core/storage';\nimport type { Redis } from '@upstash/redis';\nimport { UpstashDB, resolveUpstashConfig } from '../../db';\nimport type { UpstashDomainConfig } from '../../db';\nimport { processRecord } from '../utils';\n\n/**\n * Upstash-specific score row transformation.\n * Uses default options (no timestamp conversion).\n */\nfunction transformScoreRow(row: Record<string, any>): ScoreRowData {\n  return coreTransformScoreRow(row);\n}\n\n/** Returns true when a row matches the multi-tenant scope filters (or none provided). */\nfunction matchesTenancy(row: Record<string, any>, 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\nfunction compareScoresByCreatedAtDesc(a: Record<string, any>, b: Record<string, any>): number {\n  const createdAtDiff = new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n  if (createdAtDiff !== 0) return createdAtDiff;\n  return String(b.id ?? '').localeCompare(String(a.id ?? ''));\n}\n\nexport class ScoresUpstash extends ScoresStorage {\n  private client: Redis;\n  #db: UpstashDB;\n\n  constructor(config: UpstashDomainConfig) {\n    super();\n    const client = resolveUpstashConfig(config);\n    this.client = client;\n    this.#db = new UpstashDB({ client });\n  }\n\n  async dangerouslyClearAll(): Promise<void> {\n    await this.#db.deleteData({ tableName: TABLE_SCORERS });\n  }\n\n  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      if (!data) return null;\n      return transformScoreRow(data);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  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    const pattern = `${TABLE_SCORERS}:*`;\n    const keys = await this.#db.scanKeys(pattern);\n    const { page, perPage: perPageInput } = pagination;\n    if (keys.length === 0) {\n      return {\n        scores: [],\n        pagination: { total: 0, page, perPage: perPageInput, hasMore: false },\n      };\n    }\n    const pipeline = this.client.pipeline();\n    keys.forEach(key => pipeline.get(key));\n    const results = await pipeline.exec();\n    // Filter out nulls and by scorerId\n    const filtered = results\n      .map((raw: any) => {\n        if (!raw) return null;\n        if (typeof raw === 'string') {\n          try {\n            return JSON.parse(raw);\n          } catch {\n            return null;\n          }\n        }\n        return raw as Record<string, any>;\n      })\n      .filter((row): row is Record<string, any> => {\n        if (!row || typeof row !== 'object') return false;\n        if (row.scorerId !== scorerId) return false;\n        if (entityId && row.entityId !== entityId) return false;\n        if (entityType && row.entityType !== entityType) return false;\n        if (source && row.source !== source) return false;\n        if (!matchesTenancy(row, filters)) return false;\n        return true;\n      });\n    const perPage = normalizePerPage(perPageInput, 100); // false → MAX_SAFE_INTEGER\n    const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n    const end = perPageInput === false ? filtered.length : start + perPage;\n    const total = filtered.length;\n    const paged = [...filtered].sort(compareScoresByCreatedAtDesc).slice(start, end);\n    const scores = paged.map(row => transformScoreRow(row));\n    return {\n      scores,\n      pagination: {\n        total,\n        page,\n        perPage: perPageForResponse,\n        hasMore: end < total,\n      },\n    };\n  }\n\n  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('UPSTASH', '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    const createdAt = now;\n    const updatedAt = now;\n\n    const scoreWithId = {\n      ...validatedScore,\n      id,\n      createdAt,\n      updatedAt,\n    };\n\n    const { key, processedRecord } = processRecord(TABLE_SCORERS, scoreWithId);\n    try {\n      await this.client.set(key, processedRecord);\n      return { score: { ...validatedScore, id, createdAt, updatedAt } as ScoreRowData };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', 'SAVE_SCORE', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { id },\n        },\n        error,\n      );\n    }\n  }\n\n  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    const pattern = `${TABLE_SCORERS}:*`;\n    const keys = await this.#db.scanKeys(pattern);\n    const { page, perPage: perPageInput } = pagination;\n    if (keys.length === 0) {\n      return {\n        scores: [],\n        pagination: { total: 0, page, perPage: perPageInput, hasMore: false },\n      };\n    }\n    const pipeline = this.client.pipeline();\n    keys.forEach(key => pipeline.get(key));\n    const results = await pipeline.exec();\n    // Filter out nulls and by runId\n    const filtered = results\n      .map((raw: any) => {\n        if (!raw) return null;\n        if (typeof raw === 'string') {\n          try {\n            return JSON.parse(raw);\n          } catch {\n            return null;\n          }\n        }\n        return raw as Record<string, any>;\n      })\n      .filter(\n        (row): row is Record<string, any> =>\n          !!row && typeof row === 'object' && row.runId === runId && matchesTenancy(row, filters),\n      );\n    const total = filtered.length;\n    const perPage = normalizePerPage(perPageInput, 100); // false → MAX_SAFE_INTEGER\n    const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n    const end = perPageInput === false ? filtered.length : start + perPage;\n    const paged = [...filtered].sort(compareScoresByCreatedAtDesc).slice(start, end);\n    const scores = paged.map(row => transformScoreRow(row));\n    return {\n      scores,\n      pagination: {\n        total,\n        page,\n        perPage: perPageForResponse,\n        hasMore: end < total,\n      },\n    };\n  }\n\n  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    const pattern = `${TABLE_SCORERS}:*`;\n    const keys = await this.#db.scanKeys(pattern);\n    const { page, perPage: perPageInput } = pagination;\n    if (keys.length === 0) {\n      return {\n        scores: [],\n        pagination: { total: 0, page, perPage: perPageInput, hasMore: false },\n      };\n    }\n    const pipeline = this.client.pipeline();\n    keys.forEach(key => pipeline.get(key));\n    const results = await pipeline.exec();\n\n    const filtered = results\n      .map((raw: any) => {\n        if (!raw) return null;\n        if (typeof raw === 'string') {\n          try {\n            return JSON.parse(raw);\n          } catch {\n            return null;\n          }\n        }\n        return raw as Record<string, any>;\n      })\n      .filter((row): row is Record<string, any> => {\n        if (!row || typeof row !== 'object') return false;\n        if (row.entityId !== entityId) return false;\n        if (entityType && row.entityType !== entityType) return false;\n        if (!matchesTenancy(row, filters)) return false;\n        return true;\n      });\n    const total = filtered.length;\n    const perPage = normalizePerPage(perPageInput, 100); // false → MAX_SAFE_INTEGER\n    const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n    const end = perPageInput === false ? filtered.length : start + perPage;\n    const paged = [...filtered].sort(compareScoresByCreatedAtDesc).slice(start, end);\n    const scores = paged.map(row => transformScoreRow(row));\n    return {\n      scores,\n      pagination: {\n        total,\n        page,\n        perPage: perPageForResponse,\n        hasMore: end < total,\n      },\n    };\n  }\n\n  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    const pattern = `${TABLE_SCORERS}:*`;\n    const keys = await this.#db.scanKeys(pattern);\n    const { page, perPage: perPageInput } = pagination;\n    if (keys.length === 0) {\n      return {\n        scores: [],\n        pagination: { total: 0, page, perPage: perPageInput, hasMore: false },\n      };\n    }\n    const pipeline = this.client.pipeline();\n    keys.forEach(key => pipeline.get(key));\n    const results = await pipeline.exec();\n    // Filter out nulls and by traceId and spanId\n    const filtered = results\n      .map((raw: any) => {\n        if (!raw) return null;\n        if (typeof raw === 'string') {\n          try {\n            return JSON.parse(raw);\n          } catch {\n            return null;\n          }\n        }\n        return raw as Record<string, any>;\n      })\n      .filter((row): row is Record<string, any> => {\n        if (!row || typeof row !== 'object') return false;\n        if (row.traceId !== traceId) return false;\n        if (row.spanId !== spanId) return false;\n        if (!matchesTenancy(row, filters)) return false;\n        return true;\n      });\n    const total = filtered.length;\n    const perPage = normalizePerPage(perPageInput, 100); // false → MAX_SAFE_INTEGER\n    const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n    const end = perPageInput === false ? filtered.length : start + perPage;\n    const paged = [...filtered].sort(compareScoresByCreatedAtDesc).slice(start, end);\n    const scores = paged.map(row => transformScoreRow(row));\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  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';\nimport type { Redis } from '@upstash/redis';\nimport { UpstashDB, resolveUpstashConfig } from '../../db';\nimport type { UpstashDomainConfig } from '../../db';\nimport { getKey } from '../utils';\n\ntype WorkflowRunRecord = {\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\nexport class WorkflowsUpstash extends WorkflowsStorage {\n  private client: Redis;\n  #db: UpstashDB;\n\n  constructor(config: UpstashDomainConfig) {\n    super();\n    const client = resolveUpstashConfig(config);\n    this.client = client;\n    this.#db = new UpstashDB({ client });\n  }\n\n  supportsConcurrentUpdates(): boolean {\n    return true;\n  }\n\n  private parseWorkflowRun(row: any): 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        this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);\n      }\n    }\n\n    return {\n      workflowName: row.workflow_name,\n      runId: row.run_id,\n      snapshot: parsedSnapshot,\n      createdAt: ensureDate(row.createdAt)!,\n      updatedAt: ensureDate(row.updatedAt)!,\n      resourceId: row.resourceId,\n    };\n  }\n\n  async dangerouslyClearAll(): Promise<void> {\n    await this.#db.deleteData({ tableName: TABLE_WORKFLOW_SNAPSHOT });\n  }\n\n  private async getWorkflowRunRecord({\n    namespace,\n    runId,\n    resourceId,\n    workflowName,\n  }: {\n    namespace: string;\n    runId: string;\n    resourceId?: string;\n    workflowName?: string;\n  }) {\n    if (workflowName) {\n      const keyVariants: Array<Record<string, string>> = [\n        ...(resourceId ? [{ namespace, workflow_name: workflowName, run_id: runId, resourceId }] : []),\n        { namespace, workflow_name: workflowName, run_id: runId },\n      ];\n\n      for (const keys of keyVariants) {\n        const data = await this.#db.get<WorkflowRunRecord>({\n          tableName: TABLE_WORKFLOW_SNAPSHOT,\n          keys,\n        });\n        if (data) return data;\n      }\n    }\n\n    const key = `${getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace })}:*run_id:${runId}*`;\n    const keys = await this.#db.scanKeys(key);\n    const workflows = await Promise.all(\n      keys.map(async key => {\n        return this.client.get<WorkflowRunRecord>(key);\n      }),\n    );\n\n    return (\n      workflows.find(\n        w =>\n          w?.run_id === runId &&\n          (!workflowName || w.workflow_name === workflowName) &&\n          (!resourceId || w.resourceId === resourceId),\n      ) ?? null\n    );\n  }\n\n  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<any, any, any, any>;\n    requestContext: Record<string, any>;\n  }): Promise<Record<string, StepResult<any, any, any, any>>> {\n    try {\n      const key = getKey(TABLE_WORKFLOW_SNAPSHOT, {\n        namespace: 'workflows',\n        workflow_name: workflowName,\n        run_id: runId,\n      });\n\n      const now = new Date().toISOString();\n\n      // Use Lua script for atomic read-modify-write operation\n      // This ensures concurrent updates don't overwrite each other\n      // The script returns the updated full record as JSON string\n      const luaScript = `\n        local key = KEYS[1]\n        local stepId = ARGV[1]\n        local resultJson = ARGV[2]\n        local requestContextJson = ARGV[3]\n        local now = ARGV[4]\n        local namespace = ARGV[5]\n        local workflowName = ARGV[6]\n        local runId = ARGV[7]\n        local timestamp = tonumber(ARGV[8])\n\n        -- Get existing data\n        local existing = redis.call('GET', key)\n        local data\n        local snapshot\n\n        if existing then\n          data = cjson.decode(existing)\n          snapshot = data.snapshot\n          if type(snapshot) == 'string' then\n            snapshot = cjson.decode(snapshot)\n          end\n        else\n          -- Create new record with default snapshot\n          snapshot = {\n            context = {},\n            activePaths = {},\n            timestamp = timestamp,\n            suspendedPaths = {},\n            activeStepsPath = {},\n            resumeLabels = {},\n            serializedStepGraph = {},\n            status = 'pending',\n            value = {},\n            waitingPaths = {},\n            runId = runId,\n            requestContext = {}\n          }\n          data = {\n            namespace = namespace,\n            workflow_name = workflowName,\n            run_id = runId,\n            createdAt = now,\n            updatedAt = now\n          }\n        end\n\n        -- Initialize context if nil\n        if snapshot.context == nil then\n          snapshot.context = {}\n        end\n\n        -- Merge the new step result\n        local stepResult = cjson.decode(resultJson)\n        snapshot.context[stepId] = stepResult\n\n        -- Merge request context\n        local newRequestContext = cjson.decode(requestContextJson)\n        if snapshot.requestContext == nil then\n          snapshot.requestContext = {}\n        end\n        for k, v in pairs(newRequestContext) do\n          snapshot.requestContext[k] = v\n        end\n\n        -- Update the record\n        data.snapshot = snapshot\n        data.updatedAt = now\n\n        -- Save back\n        redis.call('SET', key, cjson.encode(data))\n\n        -- Return the full updated data\n        return cjson.encode(data)\n      `;\n\n      const resultJson = await this.client.eval(\n        luaScript,\n        [key],\n        [\n          stepId,\n          JSON.stringify(result),\n          JSON.stringify(requestContext),\n          now,\n          'workflows',\n          workflowName,\n          runId,\n          String(Date.now()),\n        ],\n      );\n\n      // Parse the result - handle both string and already-parsed object\n      let data: any;\n      if (typeof resultJson === 'string') {\n        data = JSON.parse(resultJson);\n      } else {\n        data = resultJson;\n      }\n\n      const snapshot = typeof data.snapshot === 'string' ? JSON.parse(data.snapshot) : data.snapshot;\n      return snapshot.context;\n    } catch (error) {\n      if (error instanceof MastraError) throw error;\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  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 key = getKey(TABLE_WORKFLOW_SNAPSHOT, {\n        namespace: 'workflows',\n        workflow_name: workflowName,\n        run_id: runId,\n      });\n\n      const now = new Date().toISOString();\n\n      // Use Lua script for atomic read-modify-write operation\n      // This ensures concurrent updates don't overwrite each other\n      const luaScript = `\n        local key = KEYS[1]\n        local optsJson = ARGV[1]\n        local now = ARGV[2]\n        local expectedStatusJson = ARGV[3]\n\n        -- Get existing data\n        local existing = redis.call('GET', key)\n\n        if not existing then\n          return nil\n        end\n\n        local data = cjson.decode(existing)\n        local snapshot = data.snapshot\n\n        if type(snapshot) == 'string' then\n          snapshot = cjson.decode(snapshot)\n        end\n\n        if not snapshot or not snapshot.context then\n          return nil\n        end\n\n        -- Compare-and-set guard: bail out unless the persisted status is one the caller expects.\n        -- This runs inside the same script as the write, so the check and the write are atomic.\n        if expectedStatusJson ~= '' then\n          local expected = cjson.decode(expectedStatusJson)\n          local matched = false\n          for _, status in ipairs(expected) do\n            if snapshot.status == status then\n              matched = true\n            end\n          end\n          if not matched then\n            return nil\n          end\n        end\n\n        -- Merge the new options with the existing snapshot\n        local opts = cjson.decode(optsJson)\n        for k, v in pairs(opts) do\n          snapshot[k] = v\n        end\n\n        -- Update the record\n        data.snapshot = snapshot\n        data.updatedAt = now\n\n        -- Save back\n        redis.call('SET', key, cjson.encode(data))\n\n        -- Return the full updated data\n        return cjson.encode(data)\n      `;\n\n      const { expectedStatus, ...state } = opts;\n      const expectedStatusJson =\n        expectedStatus === undefined\n          ? ''\n          : JSON.stringify(Array.isArray(expectedStatus) ? expectedStatus : [expectedStatus]);\n\n      const resultJson = await this.client.eval(luaScript, [key], [JSON.stringify(state), now, expectedStatusJson]);\n\n      if (!resultJson) {\n        return undefined;\n      }\n\n      // Parse the result - handle both string and already-parsed object\n      let data: any;\n      if (typeof resultJson === 'string') {\n        data = JSON.parse(resultJson);\n      } else {\n        data = resultJson;\n      }\n\n      const snapshot = typeof data.snapshot === 'string' ? JSON.parse(data.snapshot) : data.snapshot;\n      return snapshot;\n    } catch (error) {\n      if (error instanceof MastraError) throw error;\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  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      const now = new Date();\n      const key = getKey(TABLE_WORKFLOW_SNAPSHOT, {\n        namespace,\n        workflow_name: workflowName,\n        run_id: runId,\n        ...(resourceId ? { resourceId } : {}),\n      });\n\n      const record = {\n        namespace,\n        workflow_name: workflowName,\n        run_id: runId,\n        resourceId,\n        snapshot,\n        createdAt: (createdAt ?? now).toISOString(),\n        updatedAt: (updatedAt ?? now).toISOString(),\n      };\n\n      await (this.client as any).eval(\n        `\n        local existing = redis.call(\"GET\", KEYS[1])\n        local next = cjson.decode(ARGV[1])\n        if existing then\n          local current = cjson.decode(existing)\n          if current[\"createdAt\"] then\n            next[\"createdAt\"] = current[\"createdAt\"]\n          end\n        end\n        redis.call(\"SET\", KEYS[1], cjson.encode(next))\n        return 1\n        `,\n        [key],\n        [JSON.stringify(record)],\n      );\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  async loadWorkflowSnapshot(params: {\n    namespace: string;\n    workflowName: string;\n    runId: string;\n  }): Promise<WorkflowRunState | null> {\n    const { namespace = 'workflows', workflowName, runId } = params;\n    try {\n      const data = await this.getWorkflowRunRecord({ namespace, runId, workflowName });\n      if (!data) return null;\n      return typeof data.snapshot === 'string' ? (JSON.parse(data.snapshot) as WorkflowRunState) : data.snapshot;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  async getWorkflowRunById({\n    runId,\n    workflowName,\n  }: {\n    runId: string;\n    workflowName?: string;\n  }): Promise<WorkflowRun | null> {\n    try {\n      const data = await this.getWorkflowRunRecord({ namespace: 'workflows', runId, workflowName });\n      if (!data) return null;\n      return this.parseWorkflowRun(data);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  async deleteWorkflowRunById({ runId, workflowName }: { runId: string; workflowName: string }): Promise<void> {\n    try {\n      const record = await this.getWorkflowRunRecord({ namespace: 'workflows', runId, workflowName });\n      const key = getKey(TABLE_WORKFLOW_SNAPSHOT, {\n        namespace: 'workflows',\n        workflow_name: workflowName,\n        run_id: runId,\n        ...(record?.resourceId ? { resourceId: record.resourceId } : {}),\n      });\n      await this.client.del(key);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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  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('UPSTASH', '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      // Get workflow keys, then filter returned records. Resource-scoped keys include\n      // resourceId after run_id, so broad namespace scanning avoids missing those variants.\n      const pattern = `${getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace: 'workflows' })}:*`;\n      const keys = await this.#db.scanKeys(pattern);\n\n      // Check if we have any keys before using pipeline\n      if (keys.length === 0) {\n        return { runs: [], total: 0 };\n      }\n\n      // Use pipeline for batch fetching to improve performance\n      const pipeline = this.client.pipeline();\n      keys.forEach(key => pipeline.get(key));\n      const results = await pipeline.exec();\n\n      // Filter and transform results - handle undefined results\n      let runs = results\n        .map((result: any) => result as Record<string, any> | null)\n        .filter(\n          (record): record is Record<string, any> =>\n            record !== null && record !== undefined && typeof record === 'object' && 'workflow_name' in record,\n        )\n        // Only filter by workflowName if it was specifically requested\n        .filter(record => !workflowName || record.workflow_name === workflowName)\n        .filter(record => !resourceId || record.resourceId === resourceId)\n        .map(w => this.parseWorkflowRun(w!))\n        .filter(w => {\n          if (fromDate && w.createdAt < fromDate) return false;\n          if (toDate && w.createdAt > toDate) return false;\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                this.logger.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      // Apply pagination if requested\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) throw error;\n      throw new MastraError(\n        {\n          id: createStorageErrorId('UPSTASH', '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 { MastraCompositeStore } from '@mastra/core/storage';\nimport type { StorageDomains } from '@mastra/core/storage';\nimport { Redis } from '@upstash/redis';\nimport { BackgroundTasksUpstash } from './domains/background-tasks';\nimport { StoreMemoryUpstash } from './domains/memory';\nimport { ScoresUpstash } from './domains/scores';\nimport { WorkflowsUpstash } from './domains/workflows';\n\n// Export domain classes for direct use with MastraStorage composition\nexport { BackgroundTasksUpstash, StoreMemoryUpstash, ScoresUpstash, WorkflowsUpstash };\nexport type { UpstashDomainConfig } from './db';\n\n/**\n * Upstash configuration type.\n *\n * Accepts either:\n * - A pre-configured Redis client: `{ id, client }`\n * - URL/token config: `{ id, url, token }`\n */\nexport type UpstashConfig = {\n  id: string;\n  /**\n   * When true, automatic initialization (table creation/migrations) is disabled.\n   * This is useful for CI/CD pipelines where you want to:\n   * 1. Run migrations explicitly during deployment (not at runtime)\n   * 2. Use different credentials for schema changes vs runtime operations\n   *\n   * When disableInit is true:\n   * - The storage will not automatically create/alter tables on first use\n   * - You must call `storage.init()` explicitly in your CI/CD scripts\n   *\n   * @example\n   * // In CI/CD script:\n   * const storage = new UpstashStore({ ...config, disableInit: false });\n   * await storage.init(); // Explicitly run migrations\n   *\n   * // In runtime application:\n   * const storage = new UpstashStore({ ...config, disableInit: true });\n   * // No auto-init, tables must already exist\n   */\n  disableInit?: boolean;\n} & (\n  | {\n      /**\n       * Pre-configured Upstash Redis client.\n       * Use this when you need to configure the client before initialization,\n       * e.g., to set custom retry strategies or interceptors.\n       *\n       * @example\n       * ```typescript\n       * import { Redis } from '@upstash/redis';\n       *\n       * const client = new Redis({\n       *   url: 'https://...',\n       *   token: '...',\n       *   // Custom settings\n       *   retry: { retries: 5, backoff: (retryCount) => Math.exp(retryCount) * 50 },\n       * });\n       *\n       * const store = new UpstashStore({ id: 'my-store', client });\n       * ```\n       */\n      client: Redis;\n    }\n  | {\n      url: string;\n      token: string;\n    }\n);\n\n/**\n * Type guard for pre-configured client config\n */\nconst isClientConfig = (config: UpstashConfig): config is UpstashConfig & { client: Redis } => {\n  return 'client' in config;\n};\n\n/**\n * Upstash Redis storage adapter for Mastra.\n *\n * Access domain-specific storage via `getStore()`:\n *\n * @example\n * ```typescript\n * const storage = new UpstashStore({ id: 'my-store', url: '...', token: '...' });\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 */\nexport class UpstashStore extends MastraCompositeStore {\n  private redis: Redis;\n  stores: StorageDomains;\n\n  constructor(config: UpstashConfig) {\n    super({ id: config.id, name: 'Upstash', disableInit: config.disableInit });\n\n    // Handle pre-configured client vs creating new connection\n    if (isClientConfig(config)) {\n      // User provided a pre-configured Redis client\n      this.redis = config.client;\n    } else {\n      // Validate URL and token before creating client\n      if (!config.url || typeof config.url !== 'string' || config.url.trim() === '') {\n        throw new Error('UpstashStore: url is required and cannot be empty.');\n      }\n      if (!config.token || typeof config.token !== 'string' || config.token.trim() === '') {\n        throw new Error('UpstashStore: token is required and cannot be empty.');\n      }\n      // Create client from credentials\n      this.redis = new Redis({\n        url: config.url,\n        token: config.token,\n      });\n    }\n\n    const scores = new ScoresUpstash({ client: this.redis });\n    const workflows = new WorkflowsUpstash({ client: this.redis });\n    const memory = new StoreMemoryUpstash({ client: this.redis });\n    const backgroundTasks = new BackgroundTasksUpstash({ client: this.redis });\n\n    this.stores = {\n      scores,\n      workflows,\n      memory,\n      backgroundTasks,\n    };\n  }\n\n  async close(): Promise<void> {\n    // No explicit cleanup needed for Upstash Redis\n  }\n}\n","import { BaseFilterTranslator } from '@mastra/core/vector/filter';\nimport type { OperatorSupport, VectorFilter, OperatorValueMap } from '@mastra/core/vector/filter';\n\ntype UpstashOperatorValueMap = Omit<OperatorValueMap, '$options' | '$elemMatch'> & {\n  $contains: string;\n};\n\nexport type UpstashVectorFilter = VectorFilter<keyof UpstashOperatorValueMap, UpstashOperatorValueMap>;\n\nexport class UpstashFilterTranslator extends BaseFilterTranslator<UpstashVectorFilter, string | undefined> {\n  protected override getSupportedOperators(): OperatorSupport {\n    return {\n      ...BaseFilterTranslator.DEFAULT_OPERATORS,\n      array: ['$in', '$nin', '$all'],\n      regex: ['$regex'],\n      custom: ['$contains'],\n    };\n  }\n\n  translate(filter?: UpstashVectorFilter): string | undefined {\n    if (this.isEmpty(filter)) return undefined;\n    this.validateFilter(filter);\n    return this.translateNode(filter);\n  }\n\n  private translateNode(node: UpstashVectorFilter, path: string = ''): string {\n    if (this.isRegex(node)) {\n      throw new Error('Direct regex pattern format is not supported in Upstash');\n    }\n    if (node === null || node === undefined) {\n      throw new Error('Filtering for null/undefined values is not supported by Upstash Vector');\n    }\n\n    // Handle primitives (direct equality)\n    if (this.isPrimitive(node)) {\n      if (node === null || node === undefined) {\n        throw new Error('Filtering for null/undefined values is not supported by Upstash Vector');\n      }\n      return this.formatComparison(path, '=', node);\n    }\n\n    // Handle arrays (IN operator)\n    if (Array.isArray(node)) {\n      if (node.length === 0) {\n        return '(HAS FIELD empty AND HAS NOT FIELD empty)';\n      }\n      return `${path} IN (${this.formatArray(node)})`;\n    }\n\n    const entries = Object.entries(node as Record<string, any>);\n    const conditions: string[] = [];\n\n    for (const [key, value] of entries) {\n      const newPath = path ? `${path}.${key}` : key;\n\n      if (this.isOperator(key)) {\n        conditions.push(this.translateOperator(key, value, path));\n      } else if (typeof value === 'object' && value !== null) {\n        conditions.push(this.translateNode(value, newPath));\n      } else if (value === null || value === undefined) {\n        throw new Error('Filtering for null/undefined values is not supported by Upstash Vector');\n      } else {\n        conditions.push(this.formatComparison(newPath, '=', value));\n      }\n    }\n\n    return conditions.length > 1 ? `(${conditions.join(' AND ')})` : (conditions[0] ?? '');\n  }\n\n  private readonly COMPARISON_OPS = {\n    $eq: '=',\n    $ne: '!=',\n    $gt: '>',\n    $gte: '>=',\n    $lt: '<',\n    $lte: '<=',\n  } as const;\n\n  private translateOperator(operator: string, value: any, path: string): string {\n    // Handle comparison operators\n    if (this.isBasicOperator(operator) || this.isNumericOperator(operator)) {\n      return this.formatComparison(path, this.COMPARISON_OPS[operator], value);\n    }\n\n    // Handle special operators\n    switch (operator) {\n      case '$in':\n        if (!Array.isArray(value) || value.length === 0) {\n          return '(HAS FIELD empty AND HAS NOT FIELD empty)'; // Always false\n        }\n        return `${path} IN (${this.formatArray(value)})`;\n      case '$nin':\n        return `${path} NOT IN (${this.formatArray(value)})`;\n      case '$contains':\n        return `${path} CONTAINS ${this.formatValue(value)}`;\n      case '$regex':\n        return `${path} GLOB ${this.formatValue(value)}`;\n      case '$exists':\n        return value ? `HAS FIELD ${path}` : `HAS NOT FIELD ${path}`;\n\n      case '$and':\n        if (!Array.isArray(value) || value.length === 0) {\n          return '(HAS FIELD empty OR HAS NOT FIELD empty)';\n        }\n        return this.joinConditions(value, 'AND');\n\n      case '$or':\n        if (!Array.isArray(value) || value.length === 0) {\n          return '(HAS FIELD empty AND HAS NOT FIELD empty)';\n        }\n        return this.joinConditions(value, 'OR');\n\n      case '$not':\n        return this.formatNot(path, value);\n\n      case '$nor':\n        return this.formatNot('', { $or: value });\n      case '$all':\n        return this.translateOperator(\n          '$and',\n          value.map((item: unknown) => ({ [path]: { $contains: item } })),\n          '',\n        );\n\n      default:\n        throw new Error(`Unsupported operator: ${operator}`);\n    }\n  }\n\n  private readonly NEGATED_OPERATORS: Record<string, string> = {\n    $eq: '$ne',\n    $ne: '$eq',\n    $gt: '$lte',\n    $gte: '$lt',\n    $lt: '$gte',\n    $lte: '$gt',\n    $in: '$nin',\n    $nin: '$in',\n    $exists: '$exists', // Special case - we'll flip the value\n  };\n\n  private formatNot(path: string, value: any): string {\n    if (typeof value !== 'object') {\n      return `${path} != ${this.formatValue(value)}`;\n    }\n\n    if (!Object.keys(value).some(k => k.startsWith('$'))) {\n      const [fieldName, fieldValue] = Object.entries(value)[0] ?? [];\n\n      // If it's a nested condition with an operator\n      if (typeof fieldValue === 'object' && fieldValue !== null && Object.keys(fieldValue)[0]?.startsWith('$')) {\n        const [op, val] = Object.entries(fieldValue)[0] ?? [];\n        const negatedOp = this.NEGATED_OPERATORS[op as string];\n        if (!negatedOp) throw new Error(`Unsupported operator in NOT: ${op}`);\n\n        // Special case for $exists - negate the value instead of the operator\n        if (op === '$exists') {\n          return this.translateOperator(op, !val, fieldName ?? '');\n        }\n\n        return this.translateOperator(negatedOp, val, fieldName ?? '');\n      }\n\n      // Otherwise handle as simple field value\n      return `${fieldName} != ${this.formatValue(fieldValue)}`;\n    }\n\n    // Handle top-level operators\n    const [op, val] = Object.entries(value)[0] ?? [];\n\n    // Handle comparison operators\n    if (op === '$lt') return `${path} >= ${this.formatValue(val)}`;\n    if (op === '$lte') return `${path} > ${this.formatValue(val)}`;\n    if (op === '$gt') return `${path} <= ${this.formatValue(val)}`;\n    if (op === '$gte') return `${path} < ${this.formatValue(val)}`;\n    if (op === '$ne') return `${path} = ${this.formatValue(val)}`;\n    if (op === '$eq') return `${path} != ${this.formatValue(val)}`;\n\n    // Special cases\n    if (op === '$contains') return `${path} NOT CONTAINS ${this.formatValue(val)}`;\n    if (op === '$regex') return `${path} NOT GLOB ${this.formatValue(val)}`;\n    if (op === '$in') return `${path} NOT IN (${this.formatArray(val as any[])})`;\n    if (op === '$exists') return val ? `HAS NOT FIELD ${path}` : `HAS FIELD ${path}`;\n\n    // Transform NOT(AND) into OR(NOT) and NOT(OR) into AND(NOT)\n    if (op === '$and' || op === '$or') {\n      const newOp = op === '$and' ? '$or' : '$and';\n      const conditions = (val as any[]).map((condition: any) => {\n        const [fieldName, fieldValue] = Object.entries(condition)[0] ?? [];\n        return { [fieldName as string]: { $not: fieldValue } };\n      });\n      return this.translateOperator(newOp, conditions, '');\n    }\n\n    // NOT(NOR) is equivalent to OR\n    if (op === '$nor') {\n      return this.translateOperator('$or', val, '');\n    }\n\n    return `${path} != ${this.formatValue(val)}`;\n  }\n\n  private formatValue(value: any): string {\n    if (value === null || value === undefined) {\n      throw new Error('Filtering for null/undefined values is not supported by Upstash Vector');\n    }\n\n    if (typeof value === 'string') {\n      // Check for quotes in the string content\n      const hasSingleQuote = /'/g.test(value);\n      const hasDoubleQuote = /\"/g.test(value);\n\n      // If string has both types of quotes, escape single quotes and use single quotes\n      // If string has single quotes, use double quotes\n      // Otherwise, use single quotes (default)\n      if (hasSingleQuote && hasDoubleQuote) {\n        return `'${value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`;\n      }\n      if (hasSingleQuote) {\n        return `\"${value}\"`;\n      }\n      return `'${value}'`;\n    }\n\n    if (typeof value === 'number') {\n      // Handle scientific notation by converting to decimal\n      if (Math.abs(value) < 1e-6 || Math.abs(value) > 1e6) {\n        return value.toFixed(20).replace(/\\.?0+$/, '');\n      }\n      // Regular numbers (including zero and negative)\n      return value.toString();\n    }\n\n    return String(value);\n  }\n\n  private formatArray(values: any[]): string {\n    return values\n      .map(value => {\n        if (value === null || value === undefined) {\n          throw new Error('Filtering for null/undefined values is not supported by Upstash Vector');\n        }\n        return this.formatValue(value);\n      })\n      .join(', ');\n  }\n\n  private formatComparison(path: string, op: string, value: any): string {\n    return `${path} ${op} ${this.formatValue(value)}`;\n  }\n\n  private joinConditions(conditions: any[], operator: string): string {\n    const translated = Array.isArray(conditions)\n      ? conditions.map(c => this.translateNode(c))\n      : [this.translateNode(conditions)];\n\n    // Don't wrap in parentheses if there's only one condition\n    return `(${translated.join(` ${operator} `)})`;\n  }\n}\n","import { randomUUID } from 'node:crypto';\nimport { MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';\nimport { createVectorErrorId } from '@mastra/core/storage';\nimport { MastraVector } from '@mastra/core/vector';\nimport type {\n  CreateIndexParams,\n  DeleteIndexParams,\n  DeleteVectorParams,\n  DescribeIndexParams,\n  IndexStats,\n  QueryResult,\n  DeleteVectorsParams,\n  UpdateVectorParams,\n} from '@mastra/core/vector';\nimport { Index } from '@upstash/vector';\n\nimport { UpstashFilterTranslator } from './filter';\nimport type { UpstashVectorFilter } from './filter';\nimport type { UpstashUpsertVectorParams, UpstashQueryVectorParams, UpstashUpdateVectorParams } from './types';\n\nexport class UpstashVector extends MastraVector<UpstashVectorFilter> {\n  private client: Index;\n\n  /**\n   * Creates a new UpstashVector instance.\n   * @param {object} params - The parameters for the UpstashVector.\n   * @param {string} params.id - The unique identifier for this vector store instance.\n   * @param {string} params.url - The URL of the Upstash vector index.\n   * @param {string} params.token - The token for the Upstash vector index.\n   */\n  constructor({ url, token, id }: { url: string; token: string } & { id: string }) {\n    super({ id });\n    this.client = new Index({\n      url,\n      token,\n    });\n  }\n\n  /**\n   * Upserts vectors into the index.\n   * @param {UpsertVectorParams} params - The parameters for the upsert operation.\n   * @returns {Promise<string[]>} A promise that resolves to the IDs of the upserted vectors.\n   */\n  async upsert({\n    indexName: namespace,\n    vectors,\n    metadata,\n    ids,\n    sparseVectors,\n  }: UpstashUpsertVectorParams): Promise<string[]> {\n    const generatedIds = ids || vectors.map(() => randomUUID());\n\n    const points = vectors.map((vector, index) => ({\n      id: generatedIds[index]!,\n      vector,\n      ...(sparseVectors?.[index] && { sparseVector: sparseVectors[index] }),\n      metadata: metadata?.[index],\n    }));\n\n    try {\n      await this.client.upsert(points, {\n        namespace,\n      });\n      return generatedIds;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createVectorErrorId('UPSTASH', 'UPSERT', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { namespace, vectorCount: vectors.length },\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * Transforms a Mastra vector filter into an Upstash-compatible filter string.\n   * @param {UpstashVectorFilter} [filter] - The filter to transform.\n   * @returns {string | undefined} The transformed filter string, or undefined if no filter is provided.\n   */\n  transformFilter(filter?: UpstashVectorFilter) {\n    const translator = new UpstashFilterTranslator();\n    return translator.translate(filter);\n  }\n\n  /**\n   * Creates a new index. For Upstash, this is a no-op as indexes (known as namespaces in Upstash) are created on-the-fly.\n   * @param {CreateIndexParams} _params - The parameters for creating the index (ignored).\n   * @returns {Promise<void>} A promise that resolves when the operation is complete.\n   */\n  async createIndex(_params: CreateIndexParams): Promise<void> {\n    this.logger.debug('No need to call createIndex for Upstash');\n  }\n\n  /**\n   * Queries the vector index.\n   * @param {QueryVectorParams} params - The parameters for the query operation. indexName is the namespace in Upstash.\n   * @returns {Promise<QueryResult[]>} A promise that resolves to the query results.\n   */\n  async query({\n    indexName: namespace,\n    queryVector,\n    topK = 10,\n    filter,\n    includeVector = false,\n    sparseVector,\n    fusionAlgorithm,\n    queryMode,\n  }: UpstashQueryVectorParams): Promise<QueryResult[]> {\n    if (!queryVector) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'QUERY', 'MISSING_VECTOR'),\n        text: 'queryVector is required for Upstash queries. Metadata-only queries are not supported by this vector store.',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { indexName: namespace },\n      });\n    }\n\n    try {\n      const ns = this.client.namespace(namespace);\n\n      const filterString = this.transformFilter(filter);\n      const results = await ns.query({\n        topK,\n        vector: queryVector,\n        ...(sparseVector && { sparseVector }),\n        includeVectors: includeVector,\n        includeMetadata: true,\n        ...(filterString ? { filter: filterString } : {}),\n        ...(fusionAlgorithm && { fusionAlgorithm }),\n        ...(queryMode && { queryMode }),\n      });\n\n      // Map the results to our expected format\n      return (results || []).map(result => ({\n        id: `${result.id}`,\n        score: result.score,\n        metadata: result.metadata,\n        ...(includeVector && { vector: result.vector || [] }),\n      }));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createVectorErrorId('UPSTASH', 'QUERY', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { namespace, topK },\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * Lists all namespaces in the Upstash vector index, which correspond to indexes.\n   * @returns {Promise<string[]>} A promise that resolves to a list of index names.\n   */\n  async listIndexes(): Promise<string[]> {\n    try {\n      const indexes = await this.client.listNamespaces();\n      return indexes.filter(Boolean);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createVectorErrorId('UPSTASH', 'LIST_INDEXES', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * Retrieves statistics about a vector index.\n   *\n   * @param {string} indexName - The name of the namespace to describe\n   * @returns A promise that resolves to the index statistics including dimension, count and metric\n   */\n  async describeIndex({ indexName: namespace }: DescribeIndexParams): Promise<IndexStats> {\n    try {\n      const info = await this.client.info();\n\n      return {\n        dimension: info.dimension,\n        count: info.namespaces?.[namespace]?.vectorCount || 0,\n        metric: info?.similarityFunction?.toLowerCase() as 'cosine' | 'euclidean' | 'dotproduct',\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: createVectorErrorId('UPSTASH', 'DESCRIBE_INDEX', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { namespace },\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * Deletes an index (namespace).\n   * @param {DeleteIndexParams} params - The parameters for the delete operation.\n   * @returns {Promise<void>} A promise that resolves when the deletion is complete.\n   */\n  async deleteIndex({ indexName: namespace }: DeleteIndexParams): Promise<void> {\n    try {\n      await this.client.deleteNamespace(namespace);\n    } catch (error: any) {\n      // If the namespace doesn't exist, treat it as a no-op (already deleted)\n      const errorMessage = error?.message || '';\n      if (errorMessage.includes('does not exist') || errorMessage.includes('not found')) {\n        this.logger.info(`Namespace ${namespace} does not exist, treating as already deleted`);\n        return;\n      }\n      throw new MastraError(\n        {\n          id: createVectorErrorId('UPSTASH', 'DELETE_INDEX', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { namespace },\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * Updates a vector by its ID or multiple vectors matching a filter.\n   * @param params - Parameters containing the id or filter for targeting the vector(s) to update\n   * @param params.indexName - The name of the namespace containing the vector.\n   * @param params.id - The ID of the vector to update (mutually exclusive with filter).\n   * @param params.filter - Filter to match multiple vectors to update (mutually exclusive with id).\n   * @param params.update - An object containing the vector and/or metadata to update.\n   * @returns A promise that resolves when the update is complete.\n   * @throws Will throw an error if no updates are provided or if the update operation fails.\n   */\n  async updateVector(params: UpdateVectorParams<UpstashVectorFilter>): Promise<void> {\n    const { indexName: namespace, update } = params;\n    // Extract Upstash-specific sparseVector field from update\n    const upstashUpdate = update as UpstashUpdateVectorParams['update'];\n    const sparseVector = upstashUpdate.sparseVector;\n\n    // Validate mutually exclusive parameters\n    if ('id' in params && params.id && 'filter' in params && params.filter) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'UPDATE_VECTOR', 'MUTUALLY_EXCLUSIVE'),\n        text: 'Cannot specify both id and filter - they are mutually exclusive',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { namespace },\n      });\n    }\n\n    if (!('id' in params && params.id) && !('filter' in params && params.filter)) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'UPDATE_VECTOR', 'NO_TARGET'),\n        text: 'Either id or filter must be provided',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { namespace },\n      });\n    }\n\n    if (!update.vector && !update.metadata && !sparseVector) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'UPDATE_VECTOR', 'NO_PAYLOAD'),\n        text: 'No update data provided',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { namespace },\n      });\n    }\n\n    // Validate filter is not empty\n    if ('filter' in params && params.filter && Object.keys(params.filter).length === 0) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'UPDATE_VECTOR', 'EMPTY_FILTER'),\n        text: 'Filter cannot be an empty filter object',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { namespace },\n      });\n    }\n\n    // Note: Upstash requires both vector and metadata for upsert operations.\n    // For partial updates (metadata-only or vector-only), we fetch the existing data\n    // and merge it with the updates before calling upsert.\n\n    try {\n      const ns = this.client.namespace(namespace);\n\n      // Handle update by ID\n      if ('id' in params && params.id) {\n        const points: any = { id: params.id };\n\n        // For partial updates (metadata-only or vector-only), fetch existing data\n        if (!update.vector || !update.metadata) {\n          try {\n            const existing = await ns.fetch([params.id], {\n              includeVectors: true,\n              includeMetadata: true,\n            });\n\n            if (existing && existing.length > 0 && existing[0]) {\n              if (!update.vector && existing[0]?.vector) {\n                points.vector = existing[0].vector;\n              }\n              if (!update.metadata && existing[0]?.metadata) {\n                points.metadata = existing[0].metadata;\n              }\n            }\n          } catch (fetchError) {\n            // If fetch fails, we'll just proceed with what we have\n            this.logger.warn(`Failed to fetch existing vector ${params.id} for partial update: ${fetchError}`);\n          }\n        }\n\n        if (update.vector) points.vector = update.vector;\n        if (update.metadata) points.metadata = update.metadata;\n        if (sparseVector) points.sparseVector = sparseVector;\n\n        await ns.upsert(points);\n      }\n      // Handle update by filter\n      else if ('filter' in params && params.filter) {\n        const filterString = this.transformFilter(params.filter);\n        if (filterString) {\n          // Get index stats to know dimensions for dummy vector\n          const stats = await this.describeIndex({ indexName: namespace });\n\n          // Create a normalized dummy vector for querying (avoid zero vector for cosine similarity)\n          const dummyVector = new Array(stats.dimension).fill(1 / Math.sqrt(stats.dimension));\n\n          // Query to get all matching vectors\n          // For metadata-only updates, we need to fetch existing vectors\n          const needsVectors = !update.vector;\n          const results = await ns.query({\n            vector: dummyVector,\n            topK: 1000, // Upstash's max query limit\n            filter: filterString,\n            includeVectors: needsVectors,\n            includeMetadata: needsVectors,\n          });\n\n          // Update each matching vector\n          for (const result of results) {\n            const points: any = { id: `${result.id}` };\n\n            // For metadata-only updates, reuse existing vector\n            if (update.vector) {\n              points.vector = update.vector;\n            } else if (result.vector) {\n              points.vector = result.vector;\n            }\n\n            // For vector-only updates, reuse existing metadata\n            if (update.metadata) {\n              points.metadata = update.metadata;\n            } else if (result.metadata) {\n              points.metadata = result.metadata;\n            }\n\n            if (sparseVector) points.sparseVector = sparseVector;\n\n            await ns.upsert(points);\n          }\n        }\n      }\n    } catch (error) {\n      if (error instanceof MastraError) throw error;\n      throw new MastraError(\n        {\n          id: createVectorErrorId('UPSTASH', 'UPDATE_VECTOR', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            namespace,\n            ...('id' in params && params.id && { id: params.id }),\n            ...('filter' in params && params.filter && { filter: JSON.stringify(params.filter) }),\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * Deletes a vector by its ID.\n   * @param indexName - The name of the namespace containing the vector.\n   * @param id - The ID of the vector to delete.\n   * @returns A promise that resolves when the deletion is complete.\n   * @throws Will throw an error if the deletion operation fails.\n   */\n  async deleteVector({ indexName: namespace, id }: DeleteVectorParams): Promise<void> {\n    try {\n      const ns = this.client.namespace(namespace);\n      await ns.delete(id);\n    } catch (error) {\n      const mastraError = new MastraError(\n        {\n          id: createVectorErrorId('UPSTASH', 'DELETE_VECTOR', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            namespace,\n            ...(id && { id }),\n          },\n        },\n        error,\n      );\n      this.logger?.error(mastraError.toString());\n    }\n  }\n\n  /**\n   * Deletes multiple vectors by IDs or filter.\n   * @param indexName - The name of the namespace containing the vectors.\n   * @param ids - Array of vector IDs to delete (mutually exclusive with filter).\n   * @param filter - Filter to match vectors to delete (mutually exclusive with ids).\n   * @returns A promise that resolves when the deletion is complete.\n   * @throws Will throw an error if both ids and filter are provided, or if neither is provided.\n   */\n  async deleteVectors({ indexName: namespace, filter, ids }: DeleteVectorsParams<UpstashVectorFilter>): Promise<void> {\n    // Validate mutually exclusive parameters\n    if (ids && filter) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'DELETE_VECTORS', 'MUTUALLY_EXCLUSIVE'),\n        text: 'Cannot specify both ids and filter - they are mutually exclusive',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { namespace },\n      });\n    }\n\n    if (!ids && !filter) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'DELETE_VECTORS', 'NO_TARGET'),\n        text: 'Either filter or ids must be provided',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { namespace },\n      });\n    }\n\n    // Validate ids array is not empty\n    if (ids && ids.length === 0) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'DELETE_VECTORS', 'EMPTY_IDS'),\n        text: 'Cannot delete with empty ids array',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { namespace },\n      });\n    }\n\n    // Validate filter is not empty\n    if (filter && Object.keys(filter).length === 0) {\n      throw new MastraError({\n        id: createVectorErrorId('UPSTASH', 'DELETE_VECTORS', 'EMPTY_FILTER'),\n        text: 'Cannot delete with empty filter object',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { namespace },\n      });\n    }\n\n    try {\n      const ns = this.client.namespace(namespace);\n\n      if (ids) {\n        // Delete by IDs - Upstash's delete accepts individual IDs or arrays\n        await ns.delete(ids);\n      } else if (filter) {\n        // Delete by filter - Query first to get matching IDs, then delete\n        const filterString = this.transformFilter(filter);\n        if (filterString) {\n          // Get index stats to know dimensions for dummy vector\n          const stats = await this.describeIndex({ indexName: namespace });\n\n          // Create a normalized dummy vector for querying (avoid zero vector for cosine similarity)\n          const dummyVector = new Array(stats.dimension).fill(1 / Math.sqrt(stats.dimension));\n\n          // Query to get all matching vectors\n          const results = await ns.query({\n            vector: dummyVector,\n            topK: 1000, // Upstash's max query limit\n            filter: filterString,\n            includeVectors: false,\n            includeMetadata: false,\n          });\n\n          // Delete all matching vectors\n          const idsToDelete = results.map(r => `${r.id}`);\n          if (idsToDelete.length > 0) {\n            await ns.delete(idsToDelete);\n          }\n        }\n      }\n    } catch (error) {\n      if (error instanceof MastraError) throw error;\n      throw new MastraError(\n        {\n          id: createVectorErrorId('UPSTASH', 'DELETE_VECTORS', 'FAILED'),\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            namespace,\n            ...(filter && { filter: JSON.stringify(filter) }),\n            ...(ids && { idsCount: ids.length }),\n          },\n        },\n        error,\n      );\n    }\n  }\n}\n","/**\n * Vector store specific prompt that details supported operators and examples.\n * This prompt helps users construct valid filters for Upstash Vector.\n */\nexport const UPSTASH_PROMPT = `When querying Upstash Vector, you can ONLY use the operators listed below. Any other operators will be rejected.\nImportant: Don't explain how to construct the filter - use the specified operators and fields to search the content and return relevant results.\nIf a user tries to give an explicit operator that is not supported, reject the filter entirely and let them know that the operator is not supported.\n\nBasic Comparison Operators:\n- $eq: Exact match (default when using field: value)\n  Example: { \"category\": \"electronics\" }\n- $ne: Not equal\n  Example: { \"category\": { \"$ne\": \"electronics\" } }\n- $gt: Greater than\n  Example: { \"price\": { \"$gt\": 100 } }\n- $gte: Greater than or equal\n  Example: { \"price\": { \"$gte\": 100 } }\n- $lt: Less than\n  Example: { \"price\": { \"$lt\": 100 } }\n- $lte: Less than or equal\n  Example: { \"price\": { \"$lte\": 100 } }\n\nArray Operators:\n- $in: Match any value in array\n  Example: { \"category\": { \"$in\": [\"electronics\", \"books\"] } }\n- $nin: Does not match any value in array\n  Example: { \"category\": { \"$nin\": [\"electronics\", \"books\"] } }\n\nLogical Operators:\n- $and: Logical AND (can be implicit or explicit)\n  Implicit Example: { \"price\": { \"$gt\": 100 }, \"category\": \"electronics\" }\n  Explicit Example: { \"$and\": [{ \"price\": { \"$gt\": 100 } }, { \"category\": \"electronics\" }] }\n- $or: Logical OR\n  Example: { \"$or\": [{ \"price\": { \"$lt\": 50 } }, { \"category\": \"books\" }] }\n\nElement Operators:\n- $exists: Check if field exists\n  Example: { \"rating\": { \"$exists\": true } }\n\nRestrictions:\n- Regex patterns are not supported\n- Only $and and $or logical operators are supported at the top level\n- Empty arrays in $in/$nin will return no results\n- Nested fields are supported using dot notation\n- Multiple conditions on the same field are supported with both implicit and explicit $and\n- At least one key-value pair is required in filter object\n- Empty objects and undefined values are treated as no filter\n- Invalid types in comparison operators will throw errors\n- All non-logical operators must be used within a field condition\n  Valid: { \"field\": { \"$gt\": 100 } }\n  Valid: { \"$and\": [...] }\n  Invalid: { \"$gt\": 100 }\n- Logical operators must contain field conditions, not direct operators\n  Valid: { \"$and\": [{ \"field\": { \"$gt\": 100 } }] }\n  Invalid: { \"$and\": [{ \"$gt\": 100 }] }\n- Logical operators ($and, $or):\n  - Can only be used at top level or nested within other logical operators\n  - Can not be used on a field level, or be nested inside a field\n  - Can not be used inside an operator\n  - Valid: { \"$and\": [{ \"field\": { \"$gt\": 100 } }] }\n  - Valid: { \"$or\": [{ \"$and\": [{ \"field\": { \"$gt\": 100 } }] }] }\n  - Invalid: { \"field\": { \"$and\": [{ \"$gt\": 100 }] } }\n  - Invalid: { \"field\": { \"$or\": [{ \"$gt\": 100 }] } }\n  - Invalid: { \"field\": { \"$gt\": { \"$and\": [{...}] } } }\n\nExample Complex Query:\n{\n  \"$and\": [\n    { \"category\": { \"$in\": [\"electronics\", \"computers\"] } },\n    { \"price\": { \"$gte\": 100, \"$lte\": 1000 } },\n    { \"rating\": { \"$exists\": true, \"$gt\": 4 } },\n    { \"$or\": [\n      { \"stock\": { \"$gt\": 0 } },\n      { \"preorder\": true }\n    ]}\n  ]\n}`;\n"],"mappings":"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"}