{"version":3,"sources":["jsdelivr-header.js","/npm/@mastra/libsql@0.16.3/src/vector/filter.ts","/npm/@mastra/libsql@0.16.3/src/vector/sql-builder.ts","/npm/@mastra/libsql@0.16.3/src/vector/index.ts","/npm/@mastra/libsql@0.16.3/src/storage/domains/legacy-evals/index.ts","/npm/@mastra/libsql@0.16.3/src/storage/domains/memory/index.ts","/npm/@mastra/libsql@0.16.3/src/storage/domains/utils.ts","/npm/@mastra/libsql@0.16.3/src/storage/domains/observability/index.ts","/npm/@mastra/libsql@0.16.3/src/storage/domains/operations/index.ts","/npm/@mastra/libsql@0.16.3/src/storage/domains/scores/index.ts","/npm/@mastra/libsql@0.16.3/src/storage/domains/traces/index.ts","/npm/@mastra/libsql@0.16.3/src/storage/domains/workflows/index.ts","/npm/@mastra/libsql@0.16.3/src/storage/index.ts","/npm/@mastra/libsql@0.16.3/src/vector/prompt.ts"],"names":[],"mappings":"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","file":"/npm/@mastra/libsql@0.16.3/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@mastra/libsql@0.16.3/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import { BaseFilterTranslator } from '@mastra/core/vector/filter';\nimport type { VectorFilter, OperatorSupport, OperatorValueMap, VectorFieldValue } from '@mastra/core/vector/filter';\n\ntype LibSQLOperatorValueMap = Omit<\n  OperatorValueMap,\n  '$regex' | '$options' | '$in' | '$all' | '$nin' | '$eq' | '$ne'\n> & {\n  $size: number;\n  $contains: VectorFieldValue | Record<string, unknown>;\n  $all: VectorFieldValue;\n  $in: VectorFieldValue;\n  $nin: VectorFieldValue;\n  $eq: VectorFieldValue;\n  $ne: VectorFieldValue;\n};\nexport type LibSQLVectorFilter = VectorFilter<keyof LibSQLOperatorValueMap, LibSQLOperatorValueMap>;\n\n/**\n * Translates MongoDB-style filters to LibSQL compatible filters.\n *\n * Key differences from MongoDB:\n *\n * Logical Operators ($and, $or, $nor):\n * - Can be used at the top level or nested within fields\n * - Can take either a single condition or an array of conditions\n *\n */\nexport class LibSQLFilterTranslator extends BaseFilterTranslator<LibSQLVectorFilter> {\n  protected override getSupportedOperators(): OperatorSupport {\n    return {\n      ...BaseFilterTranslator.DEFAULT_OPERATORS,\n      regex: [],\n      custom: ['$contains', '$size'],\n    };\n  }\n\n  translate(filter?: LibSQLVectorFilter): LibSQLVectorFilter {\n    if (this.isEmpty(filter)) {\n      return filter;\n    }\n    this.validateFilter(filter);\n    return this.translateNode(filter);\n  }\n\n  private translateNode(node: LibSQLVectorFilter, currentPath: string = ''): any {\n    if (this.isRegex(node)) {\n      throw new Error('Direct regex pattern format is not supported in LibSQL');\n    }\n    // Helper to wrap result with path if needed\n    const withPath = (result: any) => (currentPath ? { [currentPath]: result } : result);\n\n    // Handle primitives\n    if (this.isPrimitive(node)) {\n      return withPath({ $eq: this.normalizeComparisonValue(node) });\n    }\n\n    // Handle arrays\n    if (Array.isArray(node)) {\n      return withPath({ $in: this.normalizeArrayValues(node) });\n    }\n\n    // Handle regex\n    // TODO: Look more into regex support for LibSQL\n    // if (node instanceof RegExp) {\n    //   return withPath(this.translateRegexPattern(node.source, node.flags));\n    // }\n\n    const entries = Object.entries(node as Record<string, any>);\n    const result: Record<string, any> = {};\n\n    // if ('$options' in node && !('$regex' in node)) {\n    //   throw new Error('$options is not valid without $regex');\n    // }\n\n    // TODO: Look more into regex support for LibSQL\n    // // Handle special regex object format\n    // if ('$regex' in node) {\n    //   const options = (node as any).$options || '';\n    //   return withPath(this.translateRegexPattern(node.$regex, options));\n    // }\n\n    // Process remaining entries\n    for (const [key, value] of entries) {\n      // // Skip options as they're handled with $regex\n      // if (key === '$options') continue;\n\n      const newPath = currentPath ? `${currentPath}.${key}` : key;\n\n      if (this.isLogicalOperator(key)) {\n        result[key] = Array.isArray(value)\n          ? value.map((filter: LibSQLVectorFilter) => this.translateNode(filter))\n          : this.translateNode(value);\n      } else if (this.isOperator(key)) {\n        if (this.isArrayOperator(key) && !Array.isArray(value) && key !== '$elemMatch') {\n          result[key] = [value];\n        } else if (this.isBasicOperator(key) && Array.isArray(value)) {\n          result[key] = JSON.stringify(value);\n        } else {\n          result[key] = value;\n        }\n      } else if (typeof value === 'object' && value !== null) {\n        // Handle nested objects\n        const hasOperators = Object.keys(value).some(k => this.isOperator(k));\n        if (hasOperators) {\n          result[newPath] = this.translateNode(value);\n        } else {\n          Object.assign(result, this.translateNode(value, newPath));\n        }\n      } else {\n        result[newPath] = this.translateNode(value);\n      }\n    }\n\n    return result;\n  }\n\n  // TODO: Look more into regex support for LibSQL\n  // private translateRegexPattern(pattern: string, options: string = ''): any {\n  //   if (!options) return { $regex: pattern };\n\n  //   const flags = options\n  //     .split('')\n  //     .filter(f => 'imsux'.includes(f))\n  //     .join('');\n\n  //   return {\n  //     $regex: pattern,\n  //     $options: flags,\n  //   };\n  // }\n}\n","import type { InValue } from '@libsql/client';\nimport { parseFieldKey } from '@mastra/core/utils';\nimport type {\n  BasicOperator,\n  NumericOperator,\n  ArrayOperator,\n  ElementOperator,\n  LogicalOperator,\n} from '@mastra/core/vector/filter';\nimport type { LibSQLVectorFilter } from './filter';\n\ntype OperatorType =\n  | BasicOperator\n  | NumericOperator\n  | ArrayOperator\n  | ElementOperator\n  | LogicalOperator\n  | '$contains'\n  | '$size';\n\ntype FilterOperator = {\n  sql: string;\n  needsValue: boolean;\n  transformValue?: () => any;\n};\n\ntype OperatorFn = (key: string, value?: any) => FilterOperator;\n\n// Helper functions to create operators\nconst createBasicOperator = (symbol: string) => {\n  return (key: string, value: any): FilterOperator => {\n    const jsonPath = getJsonPath(key);\n    return {\n      sql: `CASE \n        WHEN ? IS NULL THEN json_extract(metadata, ${jsonPath}) IS ${symbol === '=' ? '' : 'NOT'} NULL\n        ELSE json_extract(metadata, ${jsonPath}) ${symbol} ?\n      END`,\n      needsValue: true,\n      transformValue: () => {\n        // Return the values directly, not in an object\n        return [value, value];\n      },\n    };\n  };\n};\nconst createNumericOperator = (symbol: string) => {\n  return (key: string, value: any): FilterOperator => {\n    const jsonPath = getJsonPath(key);\n\n    // Check if the value is numeric or a string (like ISO date)\n    const isNumeric =\n      typeof value === 'number' || (typeof value === 'string' && !isNaN(Number(value)) && value.trim() !== '');\n\n    if (isNumeric) {\n      // For numeric values, cast to NUMERIC for proper comparison\n      return {\n        sql: `CAST(json_extract(metadata, ${jsonPath}) AS NUMERIC) ${symbol} ?`,\n        needsValue: true,\n      };\n    } else {\n      // For non-numeric strings (like ISO dates), compare as text\n      return {\n        sql: `CAST(json_extract(metadata, ${jsonPath}) AS TEXT) ${symbol} ?`,\n        needsValue: true,\n      };\n    }\n  };\n};\n\nconst validateJsonArray = (key: string) => {\n  const jsonPath = getJsonPath(key);\n  return `json_valid(json_extract(metadata, ${jsonPath}))\n   AND json_type(json_extract(metadata, ${jsonPath})) = 'array'`;\n};\n\nconst pattern = /json_extract\\(metadata, '\\$\\.(?:\"[^\"]*\"(?:\\.\"[^\"]*\")*|[^']+)'\\)/g;\n\nfunction buildElemMatchConditions(value: any) {\n  const conditions = Object.entries(value).map(([field, fieldValue]) => {\n    if (field.startsWith('$')) {\n      // Direct operators on array elements ($in, $gt, etc)\n      const { sql, values } = buildCondition('elem.value', { [field]: fieldValue }, '');\n      // Replace the metadata path with elem.value\n      const elemSql = sql.replace(pattern, 'elem.value');\n      return { sql: elemSql, values };\n    } else if (typeof fieldValue === 'object' && !Array.isArray(fieldValue)) {\n      // Nested field with operators (count: { $gt: 20 })\n      const { sql, values } = buildCondition(field, fieldValue, '');\n      // Replace the field path with elem.value path\n      const jsonPath = parseJsonPathKey(field);\n      const elemSql = sql.replace(pattern, `json_extract(elem.value, '$.${jsonPath}')`);\n      return { sql: elemSql, values };\n    } else {\n      const jsonPath = parseJsonPathKey(field);\n      // Simple field equality (warehouse: 'A')\n      return {\n        sql: `json_extract(elem.value, '$.${jsonPath}') = ?`,\n        values: [fieldValue],\n      };\n    }\n  });\n\n  return conditions;\n}\n\n// Define all filter operators\nconst FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {\n  $eq: createBasicOperator('='),\n  $ne: createBasicOperator('!='),\n  $gt: createNumericOperator('>'),\n  $gte: createNumericOperator('>='),\n  $lt: createNumericOperator('<'),\n  $lte: createNumericOperator('<='),\n\n  // Array Operators\n  $in: (key: string, value: any) => {\n    const jsonPath = getJsonPath(key);\n    const arr = Array.isArray(value) ? value : [value];\n    if (arr.length === 0) {\n      return { sql: '1 = 0', needsValue: true, transformValue: () => [] };\n    }\n    const paramPlaceholders = arr.map(() => '?').join(',');\n    return {\n      sql: `(\n      CASE\n        WHEN ${validateJsonArray(key)} THEN\n          EXISTS (\n            SELECT 1 FROM json_each(json_extract(metadata, ${jsonPath})) as elem\n            WHERE elem.value IN (SELECT value FROM json_each(?))\n          )\n        ELSE json_extract(metadata, ${jsonPath}) IN (${paramPlaceholders})\n      END\n    )`,\n      needsValue: true,\n      transformValue: () => [JSON.stringify(arr), ...arr],\n    };\n  },\n\n  $nin: (key: string, value: any) => {\n    const jsonPath = getJsonPath(key);\n    const arr = Array.isArray(value) ? value : [value];\n    if (arr.length === 0) {\n      return { sql: '1 = 1', needsValue: true, transformValue: () => [] };\n    }\n    const paramPlaceholders = arr.map(() => '?').join(',');\n    return {\n      sql: `(\n      CASE\n        WHEN ${validateJsonArray(key)} THEN\n          NOT EXISTS (\n            SELECT 1 FROM json_each(json_extract(metadata, ${jsonPath})) as elem\n            WHERE elem.value IN (SELECT value FROM json_each(?))\n          )\n        ELSE json_extract(metadata, ${jsonPath}) NOT IN (${paramPlaceholders})\n      END\n    )`,\n      needsValue: true,\n      transformValue: () => [JSON.stringify(arr), ...arr],\n    };\n  },\n  $all: (key: string, value: any) => {\n    const jsonPath = getJsonPath(key);\n    let sql: string;\n    const arrayValue = Array.isArray(value) ? value : [value];\n\n    if (arrayValue.length === 0) {\n      // If the array is empty, always return false (no matches)\n      sql = '1 = 0';\n    } else {\n      sql = `(\n      CASE\n        WHEN ${validateJsonArray(key)} THEN\n          NOT EXISTS (\n            SELECT value\n            FROM json_each(?)\n            WHERE value NOT IN (\n              SELECT value\n              FROM json_each(json_extract(metadata, ${jsonPath}))\n            )\n          )\n        ELSE FALSE\n      END\n    )`;\n    }\n\n    return {\n      sql,\n      needsValue: true,\n      transformValue: () => {\n        if (arrayValue.length === 0) {\n          return [];\n        }\n        return [JSON.stringify(arrayValue)];\n      },\n    };\n  },\n  $elemMatch: (key: string, value: any) => {\n    const jsonPath = getJsonPath(key);\n    if (typeof value !== 'object' || Array.isArray(value)) {\n      throw new Error('$elemMatch requires an object with conditions');\n    }\n\n    // For nested object conditions\n    const conditions = buildElemMatchConditions(value);\n\n    return {\n      sql: `(\n        CASE\n          WHEN ${validateJsonArray(key)} THEN\n            EXISTS (\n              SELECT 1\n              FROM json_each(json_extract(metadata, ${jsonPath})) as elem\n              WHERE ${conditions.map(c => c.sql).join(' AND ')}\n            )\n          ELSE FALSE\n        END\n      )`,\n      needsValue: true,\n      transformValue: () => conditions.flatMap(c => c.values),\n    };\n  },\n\n  // Element Operators\n  $exists: (key: string) => {\n    const jsonPath = getJsonPath(key);\n    return {\n      sql: `json_extract(metadata, ${jsonPath}) IS NOT NULL`,\n      needsValue: false,\n    };\n  },\n\n  // Logical Operators\n  $and: (key: string) => ({\n    sql: `(${key})`,\n    needsValue: false,\n  }),\n  $or: (key: string) => ({\n    sql: `(${key})`,\n    needsValue: false,\n  }),\n  $not: key => ({ sql: `NOT (${key})`, needsValue: false }),\n  $nor: (key: string) => ({\n    sql: `NOT (${key})`,\n    needsValue: false,\n  }),\n  $size: (key: string, paramIndex: number) => {\n    const jsonPath = getJsonPath(key);\n    return {\n      sql: `(\n    CASE\n      WHEN json_type(json_extract(metadata, ${jsonPath})) = 'array' THEN \n        json_array_length(json_extract(metadata, ${jsonPath})) = $${paramIndex}\n      ELSE FALSE\n    END\n  )`,\n      needsValue: true,\n    };\n  },\n  //   /**\n  //    * Regex Operators\n  //    * Supports case insensitive and multiline\n  //    */\n  //   $regex: (key: string): FilterOperator => ({\n  //     sql: `json_extract(metadata, '$.\"${toJsonPathKey(key)}\"') = ?`,\n  //     needsValue: true,\n  //     transformValue: (value: any) => {\n  //       const pattern = typeof value === 'object' ? value.$regex : value;\n  //       const options = typeof value === 'object' ? value.$options || '' : '';\n  //       let sql = `json_extract(metadata, '$.\"${toJsonPathKey(key)}\"')`;\n\n  //       // Handle multiline\n  //       //   if (options.includes('m')) {\n  //       //     sql = `REPLACE(${sql}, CHAR(10), '\\n')`;\n  //       //   }\n\n  //       //       let finalPattern = pattern;\n  //       // if (options) {\n  //       //   finalPattern = `(\\\\?${options})${pattern}`;\n  //       // }\n\n  //       //   // Handle case insensitivity\n  //       //   if (options.includes('i')) {\n  //       //     sql = `LOWER(${sql}) REGEXP LOWER(?)`;\n  //       //   } else {\n  //       //     sql = `${sql} REGEXP ?`;\n  //       //   }\n\n  //       if (options.includes('m')) {\n  //         sql = `EXISTS (\n  //         SELECT 1\n  //         FROM json_each(\n  //           json_array(\n  //             ${sql},\n  //             REPLACE(${sql}, CHAR(10), CHAR(13))\n  //           )\n  //         ) as lines\n  //         WHERE lines.value REGEXP ?\n  //       )`;\n  //       } else {\n  //         sql = `${sql} REGEXP ?`;\n  //       }\n\n  //       // Handle case insensitivity\n  //       if (options.includes('i')) {\n  //         sql = sql.replace('REGEXP ?', 'REGEXP LOWER(?)');\n  //         sql = sql.replace('value REGEXP', 'LOWER(value) REGEXP');\n  //       }\n\n  //       // Handle extended - allows whitespace and comments in pattern\n  //       if (options.includes('x')) {\n  //         // Remove whitespace and comments from pattern\n  //         const cleanPattern = pattern.replace(/\\s+|#.*$/gm, '');\n  //         return {\n  //           sql,\n  //           values: [cleanPattern],\n  //         };\n  //       }\n\n  //       return {\n  //         sql,\n  //         values: [pattern],\n  //       };\n  //     },\n  //   }),\n  $contains: (key: string, value: any) => {\n    const jsonPathKey = parseJsonPathKey(key);\n    let sql;\n    if (Array.isArray(value)) {\n      sql = `(\n        SELECT ${validateJsonArray(jsonPathKey)}\n        AND EXISTS (\n          SELECT 1\n          FROM json_each(json_extract(metadata, '$.\"${jsonPathKey}\"')) as m\n          WHERE m.value IN (SELECT value FROM json_each(?))\n        )\n      )`;\n    } else if (typeof value === 'string') {\n      sql = `lower(json_extract(metadata, '$.\"${jsonPathKey}\"')) LIKE '%' || lower(?) || '%' ESCAPE '\\\\'`;\n    } else {\n      sql = `json_extract(metadata, '$.\"${jsonPathKey}\"') = ?`;\n    }\n    return {\n      sql,\n      needsValue: true,\n      transformValue: () => {\n        if (Array.isArray(value)) {\n          return [JSON.stringify(value)];\n        }\n        if (typeof value === 'object' && value !== null) {\n          return [JSON.stringify(value)];\n        }\n        if (typeof value === 'string') {\n          return [escapeLikePattern(value)];\n        }\n        return [value];\n      },\n    };\n  },\n  /**\n   * $objectContains: True JSON containment for advanced use (deep sub-object match).\n   * Usage: { field: { $objectContains: { ...subobject } } }\n   */\n  // $objectContains: (key: string) => ({\n  //   sql: '', // Will be overridden by transformValue\n  //   needsValue: true,\n  //   transformValue: (value: any) => ({\n  //     sql: `json_type(json_extract(metadata, '$.\"${toJsonPathKey(key)}\"')) = 'object'\n  //         AND json_patch(json_extract(metadata, '$.\"${toJsonPathKey(key)}\"'), ?) = json_extract(metadata, '$.\"${toJsonPathKey(key)}\"')`,\n  //     values: [JSON.stringify(value)],\n  //   }),\n  // }),\n};\n\ninterface FilterResult {\n  sql: string;\n  values: InValue[];\n}\n\nfunction isFilterResult(obj: any): obj is FilterResult {\n  return obj && typeof obj === 'object' && typeof obj.sql === 'string' && Array.isArray(obj.values);\n}\n\nconst parseJsonPathKey = (key: string) => {\n  const parsedKey = parseFieldKey(key);\n  // Only add quotes around path segments if they contain dots\n  if (parsedKey.includes('.')) {\n    return parsedKey\n      .split('.')\n      .map(segment => `\"${segment}\"`)\n      .join('.');\n  }\n  return parsedKey;\n};\n\n// Helper to generate the correct JSON path format for LibSQL\nconst getJsonPath = (key: string) => {\n  const jsonPathKey = parseJsonPathKey(key);\n  // Always use quotes for consistency\n  return `'$.${jsonPathKey}'`;\n};\n\nfunction escapeLikePattern(str: string): string {\n  return str.replace(/([%_\\\\])/g, '\\\\$1');\n}\n\nexport function buildFilterQuery(filter: LibSQLVectorFilter): FilterResult {\n  if (!filter) {\n    return { sql: '', values: [] };\n  }\n\n  const values: InValue[] = [];\n  const conditions = Object.entries(filter)\n    .map(([key, value]) => {\n      const condition = buildCondition(key, value, '');\n      values.push(...condition.values);\n      return condition.sql;\n    })\n    .join(' AND ');\n\n  return {\n    sql: conditions ? `WHERE ${conditions}` : '',\n    values,\n  };\n}\n\nfunction buildCondition(key: string, value: any, parentPath: string): FilterResult {\n  // Handle logical operators ($and/$or)\n  if (['$and', '$or', '$not', '$nor'].includes(key)) {\n    return handleLogicalOperator(key as '$and' | '$or' | '$not' | '$nor', value, parentPath);\n  }\n\n  // If condition is not a FilterCondition object, assume it's an equality check\n  if (!value || typeof value !== 'object') {\n    const jsonPath = getJsonPath(key);\n    return {\n      sql: `json_extract(metadata, ${jsonPath}) = ?`,\n      values: [value],\n    };\n  }\n\n  //TODO: Add regex support\n  //   if ('$regex' in value) {\n  //     return handleRegexOperator(key, value);\n  //   }\n\n  // Handle operator conditions\n  return handleOperator(key, value);\n}\n\n// function handleRegexOperator(key: string, value: any): FilterResult {\n//   const operatorFn = FILTER_OPERATORS['$regex']!;\n//   const operatorResult = operatorFn(key, value);\n//   const transformed = operatorResult.transformValue ? operatorResult.transformValue(value) : value;\n\n//   return {\n//     sql: transformed.sql,\n//     values: transformed.values,\n//   };\n// }\n\nfunction handleLogicalOperator(\n  key: '$and' | '$or' | '$not' | '$nor',\n  value: LibSQLVectorFilter[] | LibSQLVectorFilter,\n  parentPath: string,\n): FilterResult {\n  // Handle empty conditions\n  if (!value || (Array.isArray(value) && value.length === 0)) {\n    switch (key) {\n      case '$and':\n      case '$nor':\n        return { sql: 'true', values: [] };\n      case '$or':\n        return { sql: 'false', values: [] };\n      case '$not':\n        throw new Error('$not operator cannot be empty');\n      default:\n        return { sql: 'true', values: [] };\n    }\n  }\n\n  if (key === '$not') {\n    // For top-level $not\n    const entries = Object.entries(value);\n    const conditions = entries.map(([fieldKey, fieldValue]) => buildCondition(fieldKey, fieldValue, key));\n    return {\n      sql: `NOT (${conditions.map(c => c.sql).join(' AND ')})`,\n      values: conditions.flatMap(c => c.values),\n    };\n  }\n\n  const values: InValue[] = [];\n  const joinOperator = key === '$or' || key === '$nor' ? 'OR' : 'AND';\n  const conditions = Array.isArray(value)\n    ? value.map(f => {\n        const entries = !!f ? Object.entries(f) : [];\n        return entries.map(([k, v]) => buildCondition(k, v, key));\n      })\n    : [buildCondition(key, value, parentPath)];\n\n  const joined = conditions\n    .flat()\n    .map(c => {\n      values.push(...c.values);\n      return c.sql;\n    })\n    .join(` ${joinOperator} `);\n\n  return {\n    sql: key === '$nor' ? `NOT (${joined})` : `(${joined})`,\n    values,\n  };\n}\n\nfunction handleOperator(key: string, value: any): FilterResult {\n  if (typeof value === 'object' && !Array.isArray(value)) {\n    const entries = Object.entries(value);\n    const results = entries.map(([operator, operatorValue]) =>\n      operator === '$not'\n        ? {\n            sql: `NOT (${Object.entries(operatorValue as Record<string, any>)\n              .map(([op, val]) => processOperator(key, op as OperatorType, val).sql)\n              .join(' AND ')})`,\n            values: Object.entries(operatorValue as Record<string, any>).flatMap(\n              ([op, val]) => processOperator(key, op as OperatorType, val).values,\n            ),\n          }\n        : processOperator(key, operator as OperatorType, operatorValue),\n    );\n\n    return {\n      sql: `(${results.map(r => r.sql).join(' AND ')})`,\n      values: results.flatMap(r => r.values),\n    };\n  }\n\n  // Handle single operator\n  const [[operator, operatorValue] = []] = Object.entries(value);\n  return processOperator(key, operator as OperatorType, operatorValue);\n}\n\nconst processOperator = (key: string, operator: OperatorType, operatorValue: any): FilterResult => {\n  if (!operator.startsWith('$') || !FILTER_OPERATORS[operator]) {\n    throw new Error(`Invalid operator: ${operator}`);\n  }\n  const operatorFn = FILTER_OPERATORS[operator]!;\n  const operatorResult = operatorFn(key, operatorValue);\n\n  if (!operatorResult.needsValue) {\n    return { sql: operatorResult.sql, values: [] };\n  }\n\n  const transformed = operatorResult.transformValue ? operatorResult.transformValue() : operatorValue;\n\n  if (isFilterResult(transformed)) {\n    return transformed;\n  }\n\n  return {\n    sql: operatorResult.sql,\n    values: Array.isArray(transformed) ? transformed : [transformed],\n  };\n};\n","import { createClient } from '@libsql/client';\nimport type { Client as TursoClient, InValue } from '@libsql/client';\n\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { parseSqlIdentifier } from '@mastra/core/utils';\nimport { MastraVector } from '@mastra/core/vector';\nimport type {\n  IndexStats,\n  QueryResult,\n  QueryVectorParams,\n  CreateIndexParams,\n  UpsertVectorParams,\n  DescribeIndexParams,\n  DeleteIndexParams,\n  DeleteVectorParams,\n  UpdateVectorParams,\n  DeleteVectorsParams,\n} from '@mastra/core/vector';\nimport type { LibSQLVectorFilter } from './filter';\nimport { LibSQLFilterTranslator } from './filter';\nimport { buildFilterQuery } from './sql-builder';\n\ninterface LibSQLQueryVectorParams extends QueryVectorParams<LibSQLVectorFilter> {\n  minScore?: number;\n}\n\nexport interface LibSQLVectorConfig {\n  connectionUrl: string;\n  authToken?: string;\n  syncUrl?: string;\n  syncInterval?: number;\n  /**\n   * Maximum number of retries for write operations if an SQLITE_BUSY error occurs.\n   * @default 5\n   */\n  maxRetries?: number;\n  /**\n   * Initial backoff time in milliseconds for retrying write operations on SQLITE_BUSY.\n   * The backoff time will double with each retry (exponential backoff).\n   * @default 100\n   */\n  initialBackoffMs?: number;\n}\n\nexport class LibSQLVector extends MastraVector<LibSQLVectorFilter> {\n  private turso: TursoClient;\n  private readonly maxRetries: number;\n  private readonly initialBackoffMs: number;\n\n  constructor({\n    connectionUrl,\n    authToken,\n    syncUrl,\n    syncInterval,\n    maxRetries = 5,\n    initialBackoffMs = 100,\n  }: LibSQLVectorConfig) {\n    super();\n\n    this.turso = createClient({\n      url: connectionUrl,\n      syncUrl: syncUrl,\n      authToken,\n      syncInterval,\n    });\n    this.maxRetries = maxRetries;\n    this.initialBackoffMs = initialBackoffMs;\n\n    if (connectionUrl.includes(`file:`) || connectionUrl.includes(`:memory:`)) {\n      this.turso\n        .execute('PRAGMA journal_mode=WAL;')\n        .then(() => this.logger.debug('LibSQLStore: PRAGMA journal_mode=WAL set.'))\n        .catch(err => this.logger.warn('LibSQLStore: Failed to set PRAGMA journal_mode=WAL.', err));\n      this.turso\n        .execute('PRAGMA busy_timeout = 5000;')\n        .then(() => this.logger.debug('LibSQLStore: PRAGMA busy_timeout=5000 set.'))\n        .catch(err => this.logger.warn('LibSQLStore: Failed to set PRAGMA busy_timeout=5000.', err));\n    }\n  }\n\n  private async executeWriteOperationWithRetry<T>(operation: () => Promise<T>, isTransaction = false): Promise<T> {\n    let attempts = 0;\n    let backoff = this.initialBackoffMs;\n    while (attempts < this.maxRetries) {\n      try {\n        return await operation();\n      } catch (error: any) {\n        if (\n          error.code === 'SQLITE_BUSY' ||\n          (error.message && error.message.toLowerCase().includes('database is locked'))\n        ) {\n          attempts++;\n          if (attempts >= this.maxRetries) {\n            this.logger.error(\n              `LibSQLVector: Operation failed after ${this.maxRetries} attempts due to: ${error.message}`,\n              error,\n            );\n            throw error;\n          }\n          this.logger.warn(\n            `LibSQLVector: Attempt ${attempts} failed due to ${isTransaction ? 'transaction ' : ''}database lock. Retrying in ${backoff}ms...`,\n          );\n          await new Promise(resolve => setTimeout(resolve, backoff));\n          backoff *= 2;\n        } else {\n          throw error;\n        }\n      }\n    }\n    throw new Error('LibSQLVector: Max retries reached, but no error was re-thrown from the loop.');\n  }\n\n  transformFilter(filter?: LibSQLVectorFilter) {\n    const translator = new LibSQLFilterTranslator();\n    return translator.translate(filter);\n  }\n\n  async query({\n    indexName,\n    queryVector,\n    topK = 10,\n    filter,\n    includeVector = false,\n    minScore = -1, // Default to -1 to include all results (cosine similarity ranges from -1 to 1)\n  }: LibSQLQueryVectorParams): Promise<QueryResult[]> {\n    try {\n      if (!Number.isInteger(topK) || topK <= 0) {\n        throw new Error('topK must be a positive integer');\n      }\n      if (!Array.isArray(queryVector) || !queryVector.every(x => typeof x === 'number' && Number.isFinite(x))) {\n        throw new Error('queryVector must be an array of finite numbers');\n      }\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_QUERY_INVALID_ARGS',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n        },\n        error,\n      );\n    }\n\n    try {\n      const parsedIndexName = parseSqlIdentifier(indexName, 'index name');\n\n      const vectorStr = `[${queryVector.join(',')}]`;\n\n      const translatedFilter = this.transformFilter(filter);\n      const { sql: filterQuery, values: filterValues } = buildFilterQuery(translatedFilter);\n      filterValues.push(minScore);\n      filterValues.push(topK);\n\n      const query = `\n      WITH vector_scores AS (\n        SELECT\n          vector_id as id,\n          (1-vector_distance_cos(embedding, '${vectorStr}')) as score,\n          metadata\n          ${includeVector ? ', vector_extract(embedding) as embedding' : ''}\n        FROM ${parsedIndexName}\n        ${filterQuery}\n      )\n      SELECT *\n      FROM vector_scores\n      WHERE score > ?\n      ORDER BY score DESC\n      LIMIT ?`;\n\n      const result = await this.turso.execute({\n        sql: query,\n        args: filterValues,\n      });\n\n      return result.rows.map(({ id, score, metadata, embedding }) => ({\n        id: id as string,\n        score: score as number,\n        metadata: JSON.parse((metadata as string) ?? '{}'),\n        ...(includeVector && embedding && { vector: JSON.parse(embedding as string) }),\n      }));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_QUERY_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  public upsert(args: UpsertVectorParams): Promise<string[]> {\n    try {\n      return this.executeWriteOperationWithRetry(() => this.doUpsert(args), true);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_UPSERT_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  private async doUpsert({ indexName, vectors, metadata, ids }: UpsertVectorParams): Promise<string[]> {\n    const tx = await this.turso.transaction('write');\n    try {\n      const parsedIndexName = parseSqlIdentifier(indexName, 'index name');\n      const vectorIds = ids || vectors.map(() => crypto.randomUUID());\n\n      for (let i = 0; i < vectors.length; i++) {\n        const query = `\n            INSERT INTO ${parsedIndexName} (vector_id, embedding, metadata)\n            VALUES (?, vector32(?), ?)\n            ON CONFLICT(vector_id) DO UPDATE SET\n              embedding = vector32(?),\n              metadata = ?\n          `;\n        await tx.execute({\n          sql: query,\n          args: [\n            vectorIds[i] as InValue,\n            JSON.stringify(vectors[i]),\n            JSON.stringify(metadata?.[i] || {}),\n            JSON.stringify(vectors[i]),\n            JSON.stringify(metadata?.[i] || {}),\n          ],\n        });\n      }\n      await tx.commit();\n      return vectorIds;\n    } catch (error) {\n      !tx.closed && (await tx.rollback());\n      if (error instanceof Error && error.message?.includes('dimensions are different')) {\n        const match = error.message.match(/dimensions are different: (\\d+) != (\\d+)/);\n        if (match) {\n          const [, actual, expected] = match;\n          throw new Error(\n            `Vector dimension mismatch: Index \"${indexName}\" expects ${expected} dimensions but got ${actual} dimensions. ` +\n              `Either use a matching embedding model or delete and recreate the index with the new dimension.`,\n          );\n        }\n      }\n      throw error;\n    }\n  }\n\n  public createIndex(args: CreateIndexParams): Promise<void> {\n    try {\n      return this.executeWriteOperationWithRetry(() => this.doCreateIndex(args));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_CREATE_INDEX_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { indexName: args.indexName, dimension: args.dimension },\n        },\n        error,\n      );\n    }\n  }\n\n  private async doCreateIndex({ indexName, dimension }: CreateIndexParams): Promise<void> {\n    if (!Number.isInteger(dimension) || dimension <= 0) {\n      throw new Error('Dimension must be a positive integer');\n    }\n    const parsedIndexName = parseSqlIdentifier(indexName, 'index name');\n    await this.turso.execute({\n      sql: `\n          CREATE TABLE IF NOT EXISTS ${parsedIndexName} (\n            id SERIAL PRIMARY KEY,\n            vector_id TEXT UNIQUE NOT NULL,\n            embedding F32_BLOB(${dimension}),\n            metadata TEXT DEFAULT '{}'\n          );\n        `,\n      args: [],\n    });\n    await this.turso.execute({\n      sql: `\n          CREATE INDEX IF NOT EXISTS ${parsedIndexName}_vector_idx\n          ON ${parsedIndexName} (libsql_vector_idx(embedding))\n        `,\n      args: [],\n    });\n  }\n\n  public deleteIndex(args: DeleteIndexParams): Promise<void> {\n    try {\n      return this.executeWriteOperationWithRetry(() => this.doDeleteIndex(args));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_DELETE_INDEX_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { indexName: args.indexName },\n        },\n        error,\n      );\n    }\n  }\n\n  private async doDeleteIndex({ indexName }: DeleteIndexParams): Promise<void> {\n    const parsedIndexName = parseSqlIdentifier(indexName, 'index name');\n    await this.turso.execute({\n      sql: `DROP TABLE IF EXISTS ${parsedIndexName}`,\n      args: [],\n    });\n  }\n\n  async listIndexes(): Promise<string[]> {\n    try {\n      const vectorTablesQuery = `\n        SELECT name FROM sqlite_master \n        WHERE type='table' \n        AND sql LIKE '%F32_BLOB%';\n      `;\n      const result = await this.turso.execute({\n        sql: vectorTablesQuery,\n        args: [],\n      });\n      return result.rows.map(row => row.name as string);\n    } catch (error: any) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_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 index to describe\n   * @returns A promise that resolves to the index statistics including dimension, count and metric\n   */\n  async describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats> {\n    try {\n      const parsedIndexName = parseSqlIdentifier(indexName, 'index name');\n      // Get table info including column info\n      const tableInfoQuery = `\n        SELECT sql \n        FROM sqlite_master \n        WHERE type='table' \n        AND name = ?;\n      `;\n      const tableInfo = await this.turso.execute({\n        sql: tableInfoQuery,\n        args: [parsedIndexName],\n      });\n\n      if (!tableInfo.rows[0]?.sql) {\n        throw new Error(`Table ${parsedIndexName} not found`);\n      }\n\n      // Extract dimension from F32_BLOB definition\n      const dimension = parseInt((tableInfo.rows[0].sql as string).match(/F32_BLOB\\((\\d+)\\)/)?.[1] || '0');\n\n      // Get row count\n      const countQuery = `\n        SELECT COUNT(*) as count\n        FROM ${parsedIndexName};\n      `;\n      const countResult = await this.turso.execute({\n        sql: countQuery,\n        args: [],\n      });\n\n      // LibSQL only supports cosine similarity currently\n      const metric: 'cosine' | 'euclidean' | 'dotproduct' = 'cosine';\n\n      return {\n        dimension,\n        count: (countResult?.rows?.[0]?.count as number) ?? 0,\n        metric,\n      };\n    } catch (e: any) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_DESCRIBE_INDEX_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { indexName },\n        },\n        e,\n      );\n    }\n  }\n\n  /**\n   * Updates a vector by its ID with the provided vector and/or metadata.\n   *\n   * @param indexName - The name of the index containing the vector.\n   * @param id - The ID of the vector to update.\n   * @param update - An object containing the vector and/or metadata to update.\n   * @param update.vector - An optional array of numbers representing the new vector.\n   * @param update.metadata - An optional record containing the new metadata.\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  public updateVector(args: UpdateVectorParams<LibSQLVectorFilter>): Promise<void> {\n    return this.executeWriteOperationWithRetry(() => this.doUpdateVector(args));\n  }\n\n  private async doUpdateVector(params: UpdateVectorParams<LibSQLVectorFilter>): Promise<void> {\n    const { indexName, update } = params;\n    const parsedIndexName = parseSqlIdentifier(indexName, 'index name');\n\n    // Validate that both id and filter are not provided at the same time\n    if ('id' in params && params.id && 'filter' in params && params.filter) {\n      throw new MastraError({\n        id: 'LIBSQL_VECTOR_UPDATE_MUTUALLY_EXCLUSIVE_PARAMS',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { indexName },\n        text: 'id and filter are mutually exclusive - provide only one',\n      });\n    }\n\n    if (!update.vector && !update.metadata) {\n      throw new MastraError({\n        id: 'LIBSQL_VECTOR_UPDATE_VECTOR_INVALID_ARGS',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { indexName },\n        text: 'No updates provided',\n      });\n    }\n\n    const updates: string[] = [];\n    const args: InValue[] = [];\n\n    if (update.vector) {\n      updates.push('embedding = vector32(?)');\n      args.push(JSON.stringify(update.vector));\n    }\n\n    if (update.metadata) {\n      updates.push('metadata = ?');\n      args.push(JSON.stringify(update.metadata));\n    }\n\n    if (updates.length === 0) {\n      return;\n    }\n\n    let whereClause: string;\n    let whereValues: InValue[];\n\n    // Type narrowing: check if updating by id or by filter\n    if ('id' in params && params.id) {\n      // Update by ID\n      whereClause = 'vector_id = ?';\n      whereValues = [params.id];\n    } else if ('filter' in params && params.filter) {\n      // Update by filter\n      const filter = params.filter;\n\n      if (!filter || Object.keys(filter).length === 0) {\n        throw new MastraError({\n          id: 'LIBSQL_VECTOR_UPDATE_EMPTY_FILTER',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { indexName },\n          text: 'Cannot update with empty filter',\n        });\n      }\n\n      const translatedFilter = this.transformFilter(filter);\n      const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);\n\n      if (!filterSql || filterSql.trim() === '') {\n        throw new MastraError({\n          id: 'LIBSQL_VECTOR_UPDATE_INVALID_FILTER',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { indexName },\n          text: 'Filter produced empty WHERE clause',\n        });\n      }\n\n      // Guard against match-all patterns that would update all vectors\n      // Normalize SQL by removing WHERE prefix and extra whitespace for pattern matching\n      const normalizedCondition = filterSql\n        .replace(/^\\s*WHERE\\s+/i, '')\n        .trim()\n        .toLowerCase();\n      const matchAllPatterns = ['true', '1 = 1', '1=1'];\n\n      if (matchAllPatterns.includes(normalizedCondition)) {\n        throw new MastraError({\n          id: 'LIBSQL_VECTOR_UPDATE_MATCH_ALL_FILTER',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { indexName, filterSql: normalizedCondition },\n          text: 'Filter matches all vectors. Provide a specific filter to update targeted vectors.',\n        });\n      }\n\n      // buildFilterQuery already includes \"WHERE\" in the SQL, so we need to extract just the condition\n      whereClause = filterSql.replace(/^WHERE\\s+/i, '');\n      whereValues = filterValues;\n    } else {\n      throw new MastraError({\n        id: 'LIBSQL_VECTOR_UPDATE_MISSING_PARAMS',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { indexName },\n        text: 'Either id or filter must be provided',\n      });\n    }\n\n    const query = `\n      UPDATE ${parsedIndexName}\n      SET ${updates.join(', ')}\n      WHERE ${whereClause};\n    `;\n\n    try {\n      await this.turso.execute({\n        sql: query,\n        args: [...args, ...whereValues],\n      });\n    } catch (error) {\n      const errorDetails: Record<string, any> = { indexName };\n\n      if ('id' in params && params.id) {\n        errorDetails.id = params.id;\n      }\n\n      if ('filter' in params && params.filter) {\n        errorDetails.filter = JSON.stringify(params.filter);\n      }\n\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_UPDATE_VECTOR_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: errorDetails,\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * Deletes a vector by its ID.\n   * @param indexName - The name of the index 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  public deleteVector(args: DeleteVectorParams): Promise<void> {\n    try {\n      return this.executeWriteOperationWithRetry(() => this.doDeleteVector(args));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_DELETE_VECTOR_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            indexName: args.indexName,\n            ...(args.id && { id: args.id }),\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  private async doDeleteVector({ indexName, id }: DeleteVectorParams): Promise<void> {\n    const parsedIndexName = parseSqlIdentifier(indexName, 'index name');\n    await this.turso.execute({\n      sql: `DELETE FROM ${parsedIndexName} WHERE vector_id = ?`,\n      args: [id],\n    });\n  }\n\n  public deleteVectors(args: DeleteVectorsParams<LibSQLVectorFilter>): Promise<void> {\n    return this.executeWriteOperationWithRetry(() => this.doDeleteVectors(args));\n  }\n\n  private async doDeleteVectors({ indexName, filter, ids }: DeleteVectorsParams<LibSQLVectorFilter>): Promise<void> {\n    const parsedIndexName = parseSqlIdentifier(indexName, 'index name');\n\n    // Validate that exactly one of filter or ids is provided\n    if (!filter && !ids) {\n      throw new MastraError({\n        id: 'LIBSQL_VECTOR_DELETE_MISSING_PARAMS',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { indexName },\n        text: 'Either filter or ids must be provided',\n      });\n    }\n\n    if (filter && ids) {\n      throw new MastraError({\n        id: 'LIBSQL_VECTOR_DELETE_CONFLICTING_PARAMS',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        details: { indexName },\n        text: 'Cannot provide both filter and ids - they are mutually exclusive',\n      });\n    }\n\n    let query: string;\n    let values: InValue[];\n\n    if (ids) {\n      // Delete by IDs\n      if (ids.length === 0) {\n        throw new MastraError({\n          id: 'LIBSQL_VECTOR_DELETE_EMPTY_IDS',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { indexName },\n          text: 'Cannot delete with empty ids array',\n        });\n      }\n\n      const placeholders = ids.map(() => '?').join(', ');\n      query = `DELETE FROM ${parsedIndexName} WHERE vector_id IN (${placeholders})`;\n      values = ids;\n    } else {\n      // Delete by filter\n      // Safety check: Don't allow empty filters to prevent accidental deletion of all vectors\n      if (!filter || Object.keys(filter).length === 0) {\n        throw new MastraError({\n          id: 'LIBSQL_VECTOR_DELETE_EMPTY_FILTER',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { indexName },\n          text: 'Cannot delete with empty filter. Use deleteIndex to delete all vectors.',\n        });\n      }\n\n      const translatedFilter = this.transformFilter(filter);\n      const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);\n\n      if (!filterSql || filterSql.trim() === '') {\n        throw new MastraError({\n          id: 'LIBSQL_VECTOR_DELETE_INVALID_FILTER',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { indexName },\n          text: 'Filter produced empty WHERE clause',\n        });\n      }\n\n      // Guard against match-all patterns that would delete all vectors\n      // Normalize SQL by removing WHERE prefix and extra whitespace for pattern matching\n      const normalizedCondition = filterSql\n        .replace(/^\\s*WHERE\\s+/i, '')\n        .trim()\n        .toLowerCase();\n      const matchAllPatterns = ['true', '1 = 1', '1=1'];\n\n      if (matchAllPatterns.includes(normalizedCondition)) {\n        throw new MastraError({\n          id: 'LIBSQL_VECTOR_DELETE_MATCH_ALL_FILTER',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: { indexName, filterSql: normalizedCondition },\n          text: 'Filter matches all vectors. Use deleteIndex to delete all vectors from an index.',\n        });\n      }\n\n      // buildFilterQuery already includes \"WHERE\" in the SQL\n      query = `DELETE FROM ${parsedIndexName} ${filterSql}`;\n      values = filterValues;\n    }\n\n    try {\n      await this.turso.execute({\n        sql: query,\n        args: values,\n      });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_DELETE_VECTORS_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            indexName,\n            ...(filter && { filter: JSON.stringify(filter) }),\n            ...(ids && { idsCount: ids.length }),\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  public truncateIndex(args: DeleteIndexParams): Promise<void> {\n    try {\n      return this.executeWriteOperationWithRetry(() => this._doTruncateIndex(args));\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_VECTOR_TRUNCATE_INDEX_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { indexName: args.indexName },\n        },\n        error,\n      );\n    }\n  }\n\n  private async _doTruncateIndex({ indexName }: DeleteIndexParams): Promise<void> {\n    await this.turso.execute({\n      sql: `DELETE FROM ${parseSqlIdentifier(indexName, 'index name')}`,\n      args: [],\n    });\n  }\n}\n","import type { Client, InValue } from '@libsql/client';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport type { MetricResult, TestInfo } from '@mastra/core/eval';\nimport { LegacyEvalsStorage, TABLE_EVALS } from '@mastra/core/storage';\nimport type { PaginationArgs, PaginationInfo, EvalRow } from '@mastra/core/storage';\n\nfunction transformEvalRow(row: Record<string, any>): EvalRow {\n  const resultValue = JSON.parse(row.result as string);\n  const testInfoValue = row.test_info ? JSON.parse(row.test_info as string) : undefined;\n\n  if (!resultValue || typeof resultValue !== 'object' || !('score' in resultValue)) {\n    throw new Error(`Invalid MetricResult format: ${JSON.stringify(resultValue)}`);\n  }\n\n  return {\n    input: row.input as string,\n    output: row.output as string,\n    result: resultValue as MetricResult,\n    agentName: row.agent_name as string,\n    metricName: row.metric_name as string,\n    instructions: row.instructions as string,\n    testInfo: testInfoValue as TestInfo,\n    globalRunId: row.global_run_id as string,\n    runId: row.run_id as string,\n    createdAt: row.created_at as string,\n  };\n}\n\nexport class LegacyEvalsLibSQL extends LegacyEvalsStorage {\n  private client: Client;\n  constructor({ client }: { client: Client }) {\n    super();\n    this.client = client;\n  }\n\n  /** @deprecated use getEvals instead */\n  async getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]> {\n    try {\n      const baseQuery = `SELECT * FROM ${TABLE_EVALS} WHERE agent_name = ?`;\n      const typeCondition =\n        type === 'test'\n          ? \" AND test_info IS NOT NULL AND test_info->>'testPath' IS NOT NULL\"\n          : type === 'live'\n            ? \" AND (test_info IS NULL OR test_info->>'testPath' IS NULL)\"\n            : '';\n\n      const result = await this.client.execute({\n        sql: `${baseQuery}${typeCondition} ORDER BY created_at DESC`,\n        args: [agentName],\n      });\n\n      return result.rows?.map(row => transformEvalRow(row)) ?? [];\n    } catch (error) {\n      // Handle case where table doesn't exist yet\n      if (error instanceof Error && error.message.includes('no such table')) {\n        return [];\n      }\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_EVALS_BY_AGENT_NAME_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { agentName },\n        },\n        error,\n      );\n    }\n  }\n\n  async getEvals(\n    options: {\n      agentName?: string;\n      type?: 'test' | 'live';\n    } & PaginationArgs = {},\n  ): Promise<PaginationInfo & { evals: EvalRow[] }> {\n    const { agentName, type, page = 0, perPage = 100, dateRange } = options;\n    const fromDate = dateRange?.start;\n    const toDate = dateRange?.end;\n\n    const conditions: string[] = [];\n    const queryParams: InValue[] = [];\n\n    if (agentName) {\n      conditions.push(`agent_name = ?`);\n      queryParams.push(agentName);\n    }\n\n    if (type === 'test') {\n      conditions.push(`(test_info IS NOT NULL AND json_extract(test_info, '$.testPath') IS NOT NULL)`);\n    } else if (type === 'live') {\n      conditions.push(`(test_info IS NULL OR json_extract(test_info, '$.testPath') IS NULL)`);\n    }\n\n    if (fromDate) {\n      conditions.push(`created_at >= ?`);\n      queryParams.push(fromDate.toISOString());\n    }\n\n    if (toDate) {\n      conditions.push(`created_at <= ?`);\n      queryParams.push(toDate.toISOString());\n    }\n\n    const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n\n    try {\n      const countResult = await this.client.execute({\n        sql: `SELECT COUNT(*) as count FROM ${TABLE_EVALS} ${whereClause}`,\n        args: queryParams,\n      });\n      const total = Number(countResult.rows?.[0]?.count ?? 0);\n\n      const currentOffset = page * perPage;\n      const hasMore = currentOffset + perPage < total;\n\n      if (total === 0) {\n        return {\n          evals: [],\n          total: 0,\n          page,\n          perPage,\n          hasMore: false,\n        };\n      }\n\n      const dataResult = await this.client.execute({\n        sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,\n        args: [...queryParams, perPage, currentOffset],\n      });\n\n      return {\n        evals: dataResult.rows?.map(row => transformEvalRow(row)) ?? [],\n        total,\n        page,\n        perPage,\n        hasMore,\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_EVALS_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n}\n","import type { Client, InValue } from '@libsql/client';\nimport type { MastraMessageContentV2 } from '@mastra/core/agent';\nimport { MessageList } from '@mastra/core/agent';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport type { MastraMessageV1, MastraMessageV2, StorageThreadType } from '@mastra/core/memory';\nimport type {\n  PaginationInfo,\n  StorageGetMessagesArg,\n  StorageResourceType,\n  ThreadSortOptions,\n} from '@mastra/core/storage';\nimport {\n  MemoryStorage,\n  resolveMessageLimit,\n  TABLE_MESSAGES,\n  TABLE_RESOURCES,\n  TABLE_THREADS,\n} from '@mastra/core/storage';\nimport { parseSqlIdentifier } from '@mastra/core/utils';\nimport type { StoreOperationsLibSQL } from '../operations';\n\nexport class MemoryLibSQL extends MemoryStorage {\n  private client: Client;\n  private operations: StoreOperationsLibSQL;\n  constructor({ client, operations }: { client: Client; operations: StoreOperationsLibSQL }) {\n    super();\n    this.client = client;\n    this.operations = operations;\n  }\n\n  private parseRow(row: any): MastraMessageV2 {\n    let content = row.content;\n    try {\n      content = JSON.parse(row.content);\n    } catch {\n      // use content as is if it's not JSON\n    }\n    const result = {\n      id: row.id,\n      content,\n      role: row.role,\n      createdAt: new Date(row.createdAt as string),\n      threadId: row.thread_id,\n      resourceId: row.resourceId,\n    } as MastraMessageV2;\n    if (row.type && row.type !== `v2`) result.type = row.type;\n    return result;\n  }\n\n  private async _getIncludedMessages({\n    threadId,\n    selectBy,\n  }: {\n    threadId: string;\n    selectBy: StorageGetMessagesArg['selectBy'];\n  }) {\n    if (!threadId.trim()) throw new Error('threadId must be a non-empty string');\n\n    const include = selectBy?.include;\n    if (!include) return null;\n\n    const unionQueries: string[] = [];\n    const params: any[] = [];\n\n    for (const inc of include) {\n      const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;\n      // if threadId is provided, use it, otherwise use threadId from args\n      const searchId = inc.threadId || threadId;\n      unionQueries.push(\n        `\n                SELECT * FROM (\n                  WITH numbered_messages AS (\n                    SELECT\n                      id, content, role, type, \"createdAt\", thread_id, \"resourceId\",\n                      ROW_NUMBER() OVER (ORDER BY \"createdAt\" ASC) as row_num\n                    FROM \"${TABLE_MESSAGES}\"\n                    WHERE thread_id = ?\n                  ),\n                  target_positions AS (\n                    SELECT row_num as target_pos\n                    FROM numbered_messages\n                    WHERE id = ?\n                  )\n                  SELECT DISTINCT m.*\n                  FROM numbered_messages m\n                  CROSS JOIN target_positions t\n                  WHERE m.row_num BETWEEN (t.target_pos - ?) AND (t.target_pos + ?)\n                ) \n                `, // Keep ASC for final sorting after fetching context\n      );\n      params.push(searchId, id, withPreviousMessages, withNextMessages);\n    }\n    const finalQuery = unionQueries.join(' UNION ALL ') + ' ORDER BY \"createdAt\" ASC';\n    const includedResult = await this.client.execute({ sql: finalQuery, args: params });\n    const includedRows = includedResult.rows?.map(row => this.parseRow(row));\n    const seen = new Set<string>();\n    const dedupedRows = includedRows.filter(row => {\n      if (seen.has(row.id)) return false;\n      seen.add(row.id);\n      return true;\n    });\n    return dedupedRows;\n  }\n\n  /**\n   * @deprecated use getMessagesPaginated instead for paginated results.\n   */\n  public async getMessages(args: StorageGetMessagesArg & { format?: 'v1' }): Promise<MastraMessageV1[]>;\n  public async getMessages(args: StorageGetMessagesArg & { format: 'v2' }): Promise<MastraMessageV2[]>;\n  public async getMessages({\n    threadId,\n    resourceId,\n    selectBy,\n    format,\n  }: StorageGetMessagesArg & {\n    format?: 'v1' | 'v2';\n  }): Promise<MastraMessageV1[] | MastraMessageV2[]> {\n    try {\n      if (!threadId.trim()) throw new Error('threadId must be a non-empty string');\n\n      const messages: MastraMessageV2[] = [];\n      const limit = resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });\n      if (selectBy?.include?.length) {\n        const includeMessages = await this._getIncludedMessages({ threadId, selectBy });\n        if (includeMessages) {\n          messages.push(...includeMessages);\n        }\n      }\n\n      const excludeIds = messages.map(m => m.id);\n      const remainingSql = `\n        SELECT \n          id, \n          content, \n          role, \n          type,\n          \"createdAt\", \n          thread_id,\n          \"resourceId\"\n        FROM \"${TABLE_MESSAGES}\"\n        WHERE thread_id = ?\n        ${excludeIds.length ? `AND id NOT IN (${excludeIds.map(() => '?').join(', ')})` : ''}\n        ORDER BY \"createdAt\" DESC\n        LIMIT ?\n      `;\n      const remainingArgs = [threadId, ...(excludeIds.length ? excludeIds : []), limit];\n      const remainingResult = await this.client.execute({ sql: remainingSql, args: remainingArgs });\n      if (remainingResult.rows) {\n        messages.push(...remainingResult.rows.map((row: any) => this.parseRow(row)));\n      }\n      messages.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());\n      const list = new MessageList().add(messages, 'memory');\n      if (format === `v2`) return list.get.all.v2();\n      return list.get.all.v1();\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_MESSAGES_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { threadId, resourceId: resourceId ?? '' },\n        },\n        error,\n      );\n    }\n  }\n\n  public async getMessagesById({\n    messageIds,\n    format,\n  }: {\n    messageIds: string[];\n    format: 'v1';\n  }): Promise<MastraMessageV1[]>;\n  public async getMessagesById({\n    messageIds,\n    format,\n  }: {\n    messageIds: string[];\n    format?: 'v2';\n  }): Promise<MastraMessageV2[]>;\n  public async getMessagesById({\n    messageIds,\n    format,\n  }: {\n    messageIds: string[];\n    format?: 'v1' | 'v2';\n  }): Promise<MastraMessageV1[] | MastraMessageV2[]> {\n    if (messageIds.length === 0) return [];\n\n    try {\n      const sql = `\n        SELECT \n          id, \n          content, \n          role, \n          type,\n          \"createdAt\", \n          thread_id,\n          \"resourceId\"\n        FROM \"${TABLE_MESSAGES}\"\n        WHERE id IN (${messageIds.map(() => '?').join(', ')})\n        ORDER BY \"createdAt\" DESC\n      `;\n      const result = await this.client.execute({ sql, args: messageIds });\n      if (!result.rows) return [];\n\n      const list = new MessageList().add(result.rows.map(this.parseRow), 'memory');\n      if (format === `v1`) return list.get.all.v1();\n      return list.get.all.v2();\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_MESSAGES_BY_ID_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { messageIds: JSON.stringify(messageIds) },\n        },\n        error,\n      );\n    }\n  }\n\n  public async getMessagesPaginated(\n    args: StorageGetMessagesArg & {\n      format?: 'v1' | 'v2';\n    },\n  ): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {\n    const { threadId, format, selectBy } = args;\n    const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};\n    const perPage =\n      perPageInput !== undefined ? perPageInput : resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });\n    const fromDate = dateRange?.start;\n    const toDate = dateRange?.end;\n\n    const messages: MastraMessageV2[] = [];\n\n    if (selectBy?.include?.length) {\n      try {\n        const includeMessages = await this._getIncludedMessages({ threadId, selectBy });\n        if (includeMessages) {\n          messages.push(...includeMessages);\n        }\n      } catch (error) {\n        throw new MastraError(\n          {\n            id: 'LIBSQL_STORE_GET_MESSAGES_PAGINATED_GET_INCLUDE_MESSAGES_FAILED',\n            domain: ErrorDomain.STORAGE,\n            category: ErrorCategory.THIRD_PARTY,\n            details: { threadId },\n          },\n          error,\n        );\n      }\n    }\n\n    try {\n      if (!threadId.trim()) throw new Error('threadId must be a non-empty string');\n\n      const currentOffset = page * perPage;\n\n      const conditions: string[] = [`thread_id = ?`];\n      const queryParams: InValue[] = [threadId];\n\n      if (fromDate) {\n        conditions.push(`\"createdAt\" >= ?`);\n        queryParams.push(fromDate.toISOString());\n      }\n      if (toDate) {\n        conditions.push(`\"createdAt\" <= ?`);\n        queryParams.push(toDate.toISOString());\n      }\n      const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n\n      const countResult = await this.client.execute({\n        sql: `SELECT COUNT(*) as count FROM ${TABLE_MESSAGES} ${whereClause}`,\n        args: queryParams,\n      });\n      const total = Number(countResult.rows?.[0]?.count ?? 0);\n\n      if (total === 0 && messages.length === 0) {\n        return {\n          messages: [],\n          total: 0,\n          page,\n          perPage,\n          hasMore: false,\n        };\n      }\n\n      const excludeIds = messages.map(m => m.id);\n      const excludeIdsParam = excludeIds.map((_, idx) => `$${idx + queryParams.length + 1}`).join(', ');\n\n      const dataResult = await this.client.execute({\n        sql: `SELECT id, content, role, type, \"createdAt\", \"resourceId\", \"thread_id\" FROM ${TABLE_MESSAGES} ${whereClause} ${excludeIds.length ? `AND id NOT IN (${excludeIdsParam})` : ''} ORDER BY \"createdAt\" DESC LIMIT ? OFFSET ?`,\n        args: [...queryParams, ...excludeIds, perPage, currentOffset],\n      });\n\n      messages.push(...(dataResult.rows || []).map((row: any) => this.parseRow(row)));\n\n      const list = new MessageList().add(messages, 'memory');\n      let messagesToReturn = format === 'v1' ? list.get.all.v1() : list.get.all.v2();\n\n      // Always sort messages by createdAt to ensure correct chronological order\n      // This is critical when `include` parameter brings in messages from semantic recall\n      messagesToReturn = messagesToReturn.sort(\n        (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime(),\n      );\n\n      return {\n        messages: messagesToReturn,\n        total,\n        page,\n        perPage,\n        hasMore: currentOffset + messages.length < total,\n      };\n    } catch (error) {\n      const mastraError = new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_MESSAGES_PAGINATED_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { threadId },\n        },\n        error,\n      );\n      this.logger?.trackException?.(mastraError);\n      this.logger?.error?.(mastraError.toString());\n      return { messages: [], total: 0, page, perPage, hasMore: false };\n    }\n  }\n\n  async saveMessages(args: { messages: MastraMessageV1[]; format?: undefined | 'v1' }): Promise<MastraMessageV1[]>;\n  async saveMessages(args: { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[]>;\n  async saveMessages({\n    messages,\n    format,\n  }:\n    | { messages: MastraMessageV1[]; format?: undefined | 'v1' }\n    | { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[] | MastraMessageV1[]> {\n    if (messages.length === 0) return messages;\n\n    try {\n      const threadId = messages[0]?.threadId;\n      if (!threadId) {\n        throw new Error('Thread ID is required');\n      }\n\n      // Prepare batch statements for all messages\n      const batchStatements = messages.map(message => {\n        const time = message.createdAt || new Date();\n        if (!message.threadId) {\n          throw new Error(\n            `Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`,\n          );\n        }\n        if (!message.resourceId) {\n          throw new Error(\n            `Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`,\n          );\n        }\n        return {\n          sql: `INSERT INTO \"${TABLE_MESSAGES}\" (id, thread_id, content, role, type, \"createdAt\", \"resourceId\") \n                  VALUES (?, ?, ?, ?, ?, ?, ?)\n                  ON CONFLICT(id) DO UPDATE SET\n                    thread_id=excluded.thread_id,\n                    content=excluded.content,\n                    role=excluded.role,\n                    type=excluded.type,\n                    \"resourceId\"=excluded.\"resourceId\"\n                `,\n          args: [\n            message.id,\n            message.threadId!,\n            typeof message.content === 'object' ? JSON.stringify(message.content) : message.content,\n            message.role,\n            message.type || 'v2',\n            time instanceof Date ? time.toISOString() : time,\n            message.resourceId,\n          ],\n        };\n      });\n\n      const now = new Date().toISOString();\n      batchStatements.push({\n        sql: `UPDATE \"${TABLE_THREADS}\" SET \"updatedAt\" = ? WHERE id = ?`,\n        args: [now, threadId],\n      });\n\n      // Execute in batches to avoid potential limitations\n      const BATCH_SIZE = 50; // Safe batch size for libsql\n\n      // Separate message statements from thread update\n      const messageStatements = batchStatements.slice(0, -1);\n      const threadUpdateStatement = batchStatements[batchStatements.length - 1];\n\n      // Process message statements in batches\n      for (let i = 0; i < messageStatements.length; i += BATCH_SIZE) {\n        const batch = messageStatements.slice(i, i + BATCH_SIZE);\n        if (batch.length > 0) {\n          await this.client.batch(batch, 'write');\n        }\n      }\n\n      // Execute thread update separately\n      if (threadUpdateStatement) {\n        await this.client.execute(threadUpdateStatement);\n      }\n\n      const list = new MessageList().add(messages, 'memory');\n      if (format === `v2`) return list.get.all.v2();\n      return list.get.all.v1();\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_SAVE_MESSAGES_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  async updateMessages({\n    messages,\n  }: {\n    messages: (Partial<Omit<MastraMessageV2, 'createdAt'>> & {\n      id: string;\n      content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };\n    })[];\n  }): Promise<MastraMessageV2[]> {\n    if (messages.length === 0) {\n      return [];\n    }\n\n    const messageIds = messages.map(m => m.id);\n    const placeholders = messageIds.map(() => '?').join(',');\n\n    const selectSql = `SELECT * FROM ${TABLE_MESSAGES} WHERE id IN (${placeholders})`;\n    const existingResult = await this.client.execute({ sql: selectSql, args: messageIds });\n    const existingMessages: MastraMessageV2[] = existingResult.rows.map(row => this.parseRow(row));\n\n    if (existingMessages.length === 0) {\n      return [];\n    }\n\n    const batchStatements = [];\n    const threadIdsToUpdate = new Set<string>();\n    const columnMapping: Record<string, string> = {\n      threadId: 'thread_id',\n    };\n\n    for (const existingMessage of existingMessages) {\n      const updatePayload = messages.find(m => m.id === existingMessage.id);\n      if (!updatePayload) continue;\n\n      const { 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      }\n\n      const setClauses = [];\n      const args: InValue[] = [];\n      const updatableFields = { ...fieldsToUpdate };\n\n      // Special handling for the 'content' field to merge instead of overwrite\n      if (updatableFields.content) {\n        const newContent = {\n          ...existingMessage.content,\n          ...updatableFields.content,\n          // Deep merge metadata if it exists on both\n          ...(existingMessage.content?.metadata && updatableFields.content.metadata\n            ? {\n                metadata: {\n                  ...existingMessage.content.metadata,\n                  ...updatableFields.content.metadata,\n                },\n              }\n            : {}),\n        };\n        setClauses.push(`${parseSqlIdentifier('content', 'column name')} = ?`);\n        args.push(JSON.stringify(newContent));\n        delete updatableFields.content;\n      }\n\n      for (const key in updatableFields) {\n        if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {\n          const dbKey = columnMapping[key] || key;\n          setClauses.push(`${parseSqlIdentifier(dbKey, 'column name')} = ?`);\n          let value = updatableFields[key as keyof typeof updatableFields];\n\n          if (typeof value === 'object' && value !== null) {\n            value = JSON.stringify(value);\n          }\n          args.push(value as InValue);\n        }\n      }\n\n      if (setClauses.length === 0) continue;\n\n      args.push(id);\n\n      const sql = `UPDATE ${TABLE_MESSAGES} SET ${setClauses.join(', ')} WHERE id = ?`;\n      batchStatements.push({ sql, args });\n    }\n\n    if (batchStatements.length === 0) {\n      return existingMessages;\n    }\n\n    const now = new Date().toISOString();\n    for (const threadId of threadIdsToUpdate) {\n      if (threadId) {\n        batchStatements.push({\n          sql: `UPDATE ${TABLE_THREADS} SET updatedAt = ? WHERE id = ?`,\n          args: [now, threadId],\n        });\n      }\n    }\n\n    await this.client.batch(batchStatements, 'write');\n\n    const updatedResult = await this.client.execute({ sql: selectSql, args: messageIds });\n    return updatedResult.rows.map(row => this.parseRow(row));\n  }\n\n  async deleteMessages(messageIds: string[]): Promise<void> {\n    if (!messageIds || messageIds.length === 0) {\n      return;\n    }\n\n    try {\n      // Process in batches to avoid SQL parameter limits\n      const BATCH_SIZE = 100;\n      const threadIds = new Set<string>();\n\n      // Use a transaction to ensure consistency\n      const tx = await this.client.transaction('write');\n\n      try {\n        for (let i = 0; i < messageIds.length; i += BATCH_SIZE) {\n          const batch = messageIds.slice(i, i + BATCH_SIZE);\n          const placeholders = batch.map(() => '?').join(',');\n\n          // Get thread IDs for this batch\n          const result = await tx.execute({\n            sql: `SELECT DISTINCT thread_id FROM \"${TABLE_MESSAGES}\" WHERE id IN (${placeholders})`,\n            args: batch,\n          });\n\n          result.rows?.forEach(row => {\n            if (row.thread_id) threadIds.add(row.thread_id as string);\n          });\n\n          // Delete messages in this batch\n          await tx.execute({\n            sql: `DELETE FROM \"${TABLE_MESSAGES}\" WHERE id IN (${placeholders})`,\n            args: batch,\n          });\n        }\n\n        // Update thread timestamps within the transaction\n        if (threadIds.size > 0) {\n          const now = new Date().toISOString();\n          for (const threadId of threadIds) {\n            await tx.execute({\n              sql: `UPDATE \"${TABLE_THREADS}\" SET \"updatedAt\" = ? WHERE id = ?`,\n              args: [now, threadId],\n            });\n          }\n        }\n\n        // Commit the transaction\n        await tx.commit();\n      } catch (error) {\n        // Rollback on error\n        await tx.rollback();\n        throw error;\n      }\n\n      // TODO: Delete from vector store if semantic recall is enabled\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_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  async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {\n    const result = await this.operations.load<StorageResourceType>({\n      tableName: TABLE_RESOURCES,\n      keys: { id: resourceId },\n    });\n\n    if (!result) {\n      return null;\n    }\n\n    return {\n      ...result,\n      // Ensure workingMemory is always returned as a string, even if auto-parsed as JSON\n      workingMemory:\n        result.workingMemory && typeof result.workingMemory === 'object'\n          ? JSON.stringify(result.workingMemory)\n          : result.workingMemory,\n      metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,\n      createdAt: new Date(result.createdAt),\n      updatedAt: new Date(result.updatedAt),\n    };\n  }\n\n  async saveResource({ resource }: { resource: StorageResourceType }): Promise<StorageResourceType> {\n    await this.operations.insert({\n      tableName: TABLE_RESOURCES,\n      record: {\n        ...resource,\n        metadata: JSON.stringify(resource.metadata),\n      },\n    });\n\n    return resource;\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    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    const updates: string[] = [];\n    const values: InValue[] = [];\n\n    if (workingMemory !== undefined) {\n      updates.push('workingMemory = ?');\n      values.push(workingMemory);\n    }\n\n    if (metadata) {\n      updates.push('metadata = ?');\n      values.push(JSON.stringify(updatedResource.metadata));\n    }\n\n    updates.push('updatedAt = ?');\n    values.push(updatedResource.updatedAt.toISOString());\n\n    values.push(resourceId);\n\n    await this.client.execute({\n      sql: `UPDATE ${TABLE_RESOURCES} SET ${updates.join(', ')} WHERE id = ?`,\n      args: values,\n    });\n\n    return updatedResource;\n  }\n\n  async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {\n    try {\n      const result = await this.operations.load<\n        Omit<StorageThreadType, 'createdAt' | 'updatedAt'> & { createdAt: string; updatedAt: string }\n      >({\n        tableName: TABLE_THREADS,\n        keys: { id: threadId },\n      });\n\n      if (!result) {\n        return null;\n      }\n\n      return {\n        ...result,\n        metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,\n        createdAt: new Date(result.createdAt),\n        updatedAt: new Date(result.updatedAt),\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_THREAD_BY_ID_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { threadId },\n        },\n        error,\n      );\n    }\n  }\n\n  /**\n   * @deprecated use getThreadsByResourceIdPaginated instead for paginated results.\n   */\n  public async getThreadsByResourceId(args: { resourceId: string } & ThreadSortOptions): Promise<StorageThreadType[]> {\n    const resourceId = args.resourceId;\n    const orderBy = this.castThreadOrderBy(args.orderBy);\n    const sortDirection = this.castThreadSortDirection(args.sortDirection);\n\n    try {\n      const baseQuery = `FROM ${TABLE_THREADS} WHERE resourceId = ?`;\n      const queryParams: InValue[] = [resourceId];\n\n      const mapRowToStorageThreadType = (row: any): StorageThreadType => ({\n        id: row.id as string,\n        resourceId: row.resourceId as string,\n        title: row.title as string,\n        createdAt: new Date(row.createdAt as string), // Convert string to Date\n        updatedAt: new Date(row.updatedAt as string), // Convert string to Date\n        metadata: typeof row.metadata === 'string' ? JSON.parse(row.metadata) : row.metadata,\n      });\n\n      // Non-paginated path\n      const result = await this.client.execute({\n        sql: `SELECT * ${baseQuery} ORDER BY ${orderBy} ${sortDirection}`,\n        args: queryParams,\n      });\n\n      if (!result.rows) {\n        return [];\n      }\n      return result.rows.map(mapRowToStorageThreadType);\n    } catch (error) {\n      const mastraError = new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { resourceId },\n        },\n        error,\n      );\n      this.logger?.trackException?.(mastraError);\n      this.logger?.error?.(mastraError.toString());\n      return [];\n    }\n  }\n\n  public async getThreadsByResourceIdPaginated(\n    args: {\n      resourceId: string;\n      page: number;\n      perPage: number;\n    } & ThreadSortOptions,\n  ): Promise<PaginationInfo & { threads: StorageThreadType[] }> {\n    const { resourceId, page = 0, perPage = 100 } = args;\n    const orderBy = this.castThreadOrderBy(args.orderBy);\n    const sortDirection = this.castThreadSortDirection(args.sortDirection);\n\n    try {\n      const baseQuery = `FROM ${TABLE_THREADS} WHERE resourceId = ?`;\n      const queryParams: InValue[] = [resourceId];\n\n      const mapRowToStorageThreadType = (row: any): StorageThreadType => ({\n        id: row.id as string,\n        resourceId: row.resourceId as string,\n        title: row.title as string,\n        createdAt: new Date(row.createdAt as string), // Convert string to Date\n        updatedAt: new Date(row.updatedAt as string), // Convert string to Date\n        metadata: typeof row.metadata === 'string' ? JSON.parse(row.metadata) : row.metadata,\n      });\n\n      const currentOffset = page * perPage;\n\n      const countResult = await this.client.execute({\n        sql: `SELECT COUNT(*) as count ${baseQuery}`,\n        args: queryParams,\n      });\n      const total = Number(countResult.rows?.[0]?.count ?? 0);\n\n      if (total === 0) {\n        return {\n          threads: [],\n          total: 0,\n          page,\n          perPage,\n          hasMore: false,\n        };\n      }\n\n      const dataResult = await this.client.execute({\n        sql: `SELECT * ${baseQuery} ORDER BY ${orderBy} ${sortDirection} LIMIT ? OFFSET ?`,\n        args: [...queryParams, perPage, currentOffset],\n      });\n\n      const threads = (dataResult.rows || []).map(mapRowToStorageThreadType);\n\n      return {\n        threads,\n        total,\n        page,\n        perPage,\n        hasMore: currentOffset + threads.length < total,\n      };\n    } catch (error) {\n      const mastraError = new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { resourceId },\n        },\n        error,\n      );\n      this.logger?.trackException?.(mastraError);\n      this.logger?.error?.(mastraError.toString());\n      return { threads: [], total: 0, page, perPage, hasMore: false };\n    }\n  }\n\n  async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {\n    try {\n      await this.operations.insert({\n        tableName: TABLE_THREADS,\n        record: {\n          ...thread,\n          metadata: JSON.stringify(thread.metadata),\n        },\n      });\n\n      return thread;\n    } catch (error) {\n      const mastraError = new MastraError(\n        {\n          id: 'LIBSQL_STORE_SAVE_THREAD_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { threadId: thread.id },\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: 'LIBSQL_STORE_UPDATE_THREAD_FAILED_THREAD_NOT_FOUND',\n        domain: ErrorDomain.STORAGE,\n        category: ErrorCategory.USER,\n        text: `Thread ${id} not found`,\n        details: {\n          status: 404,\n          threadId: id,\n        },\n      });\n    }\n\n    const updatedThread = {\n      ...thread,\n      title,\n      metadata: {\n        ...thread.metadata,\n        ...metadata,\n      },\n    };\n\n    try {\n      await this.client.execute({\n        sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = ? WHERE id = ?`,\n        args: [title, JSON.stringify(updatedThread.metadata), id],\n      });\n\n      return updatedThread;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_UPDATE_THREAD_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          text: `Failed to update thread ${id}`,\n          details: { threadId: id },\n        },\n        error,\n      );\n    }\n  }\n\n  async deleteThread({ threadId }: { threadId: string }): Promise<void> {\n    // Delete messages for this thread (manual step)\n    try {\n      await this.client.execute({\n        sql: `DELETE FROM ${TABLE_MESSAGES} WHERE thread_id = ?`,\n        args: [threadId],\n      });\n      await this.client.execute({\n        sql: `DELETE FROM ${TABLE_THREADS} WHERE id = ?`,\n        args: [threadId],\n      });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_DELETE_THREAD_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: { threadId },\n        },\n        error,\n      );\n    }\n    // TODO: Need to check if CASCADE is enabled so that messages will be automatically deleted due to CASCADE constraint\n  }\n}\n","import type { InValue } from '@libsql/client';\nimport type { IMastraLogger } from '@mastra/core/logger';\nimport { safelyParseJSON, TABLE_SCHEMAS } from '@mastra/core/storage';\nimport type { PaginationArgs, StorageColumn, TABLE_NAMES } from '@mastra/core/storage';\nimport { parseSqlIdentifier } from '@mastra/core/utils';\n\nexport function createExecuteWriteOperationWithRetry({\n  logger,\n  maxRetries,\n  initialBackoffMs,\n}: {\n  logger: IMastraLogger;\n  maxRetries: number;\n  initialBackoffMs: number;\n}) {\n  return async function executeWriteOperationWithRetry<T>(\n    operationFn: () => Promise<T>,\n    operationDescription: string,\n  ): Promise<T> {\n    let retries = 0;\n\n    while (true) {\n      try {\n        return await operationFn();\n      } catch (error: any) {\n        if (\n          error.message &&\n          (error.message.includes('SQLITE_BUSY') || error.message.includes('database is locked')) &&\n          retries < maxRetries\n        ) {\n          retries++;\n          const backoffTime = initialBackoffMs * Math.pow(2, retries - 1);\n          logger.warn(\n            `LibSQLStore: Encountered SQLITE_BUSY during ${operationDescription}. Retrying (${retries}/${maxRetries}) in ${backoffTime}ms...`,\n          );\n          await new Promise(resolve => setTimeout(resolve, backoffTime));\n        } else {\n          logger.error(`LibSQLStore: Error during ${operationDescription} after ${retries} retries: ${error}`);\n          throw error;\n        }\n      }\n    }\n  };\n}\n\nexport function prepareStatement({ tableName, record }: { tableName: TABLE_NAMES; record: Record<string, any> }): {\n  sql: string;\n  args: InValue[];\n} {\n  const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n  const columns = Object.keys(record).map(col => parseSqlIdentifier(col, 'column name'));\n  const values = Object.values(record).map(v => {\n    if (typeof v === `undefined` || v === null) {\n      // returning an undefined value will cause libsql to throw\n      return null;\n    }\n    if (v instanceof Date) {\n      return v.toISOString();\n    }\n    return typeof v === 'object' ? JSON.stringify(v) : v;\n  });\n  const placeholders = values.map(() => '?').join(', ');\n\n  return {\n    sql: `INSERT OR REPLACE INTO ${parsedTableName} (${columns.join(', ')}) VALUES (${placeholders})`,\n    args: values,\n  };\n}\n\nexport function prepareUpdateStatement({\n  tableName,\n  updates,\n  keys,\n}: {\n  tableName: TABLE_NAMES;\n  updates: Record<string, any>;\n  keys: Record<string, any>;\n}): {\n  sql: string;\n  args: InValue[];\n} {\n  const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n  const schema = TABLE_SCHEMAS[tableName];\n\n  // Prepare SET clause\n  const updateColumns = Object.keys(updates).map(col => parseSqlIdentifier(col, 'column name'));\n  const updateValues = Object.values(updates).map(transformToSqlValue);\n  const setClause = updateColumns.map(col => `${col} = ?`).join(', ');\n\n  const whereClause = prepareWhereClause(keys, schema);\n\n  return {\n    sql: `UPDATE ${parsedTableName} SET ${setClause}${whereClause.sql}`,\n    args: [...updateValues, ...whereClause.args],\n  };\n}\n\nexport function transformToSqlValue(value: any): InValue {\n  if (typeof value === 'undefined' || value === null) {\n    return null;\n  }\n  if (value instanceof Date) {\n    return value.toISOString();\n  }\n  return typeof value === 'object' ? JSON.stringify(value) : value;\n}\n\nexport function prepareDeleteStatement({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, any> }): {\n  sql: string;\n  args: InValue[];\n} {\n  const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n  const whereClause = prepareWhereClause(keys, TABLE_SCHEMAS[tableName]);\n\n  return {\n    sql: `DELETE FROM ${parsedTableName}${whereClause.sql}`,\n    args: whereClause.args,\n  };\n}\n\ntype WhereValue = InValue | { startAt?: InValue; endAt?: InValue };\n\nexport function prepareWhereClause(\n  filters: Record<string, WhereValue>,\n  schema: Record<string, StorageColumn>,\n): {\n  sql: string;\n  args: InValue[];\n} {\n  const conditions: string[] = [];\n  const args: InValue[] = [];\n\n  for (const [columnName, filterValue] of Object.entries(filters)) {\n    const column = schema[columnName];\n    if (!column) {\n      throw new Error(`Unknown column: ${columnName}`);\n    }\n\n    const parsedColumn = parseSqlIdentifier(columnName, 'column name');\n    const result = buildCondition(parsedColumn, filterValue);\n\n    conditions.push(result.condition);\n    args.push(...result.args);\n  }\n\n  return {\n    sql: conditions.length > 0 ? ` WHERE ${conditions.join(' AND ')}` : '',\n    args,\n  };\n}\n\nfunction buildCondition(columnName: string, filterValue: WhereValue): { condition: string; args: InValue[] } {\n  // Handle null values - IS NULL\n  if (filterValue === null) {\n    return { condition: `${columnName} IS NULL`, args: [] };\n  }\n\n  // Handle date range objects\n  if (typeof filterValue === 'object' && filterValue !== null && ('startAt' in filterValue || 'endAt' in filterValue)) {\n    return buildDateRangeCondition(columnName, filterValue);\n  }\n\n  // Handle exact match\n  return {\n    condition: `${columnName} = ?`,\n    args: [transformToSqlValue(filterValue)],\n  };\n}\n\nfunction buildDateRangeCondition(\n  columnName: string,\n  range: { startAt?: InValue; endAt?: InValue },\n): { condition: string; args: InValue[] } {\n  const conditions: string[] = [];\n  const args: InValue[] = [];\n\n  if (range.startAt !== undefined) {\n    conditions.push(`${columnName} >= ?`);\n    args.push(transformToSqlValue(range.startAt));\n  }\n\n  if (range.endAt !== undefined) {\n    conditions.push(`${columnName} <= ?`);\n    args.push(transformToSqlValue(range.endAt));\n  }\n\n  if (conditions.length === 0) {\n    throw new Error('Date range must specify at least startAt or endAt');\n  }\n\n  return {\n    condition: conditions.join(' AND '),\n    args,\n  };\n}\n\ntype DateRangeFilter = {\n  startAt?: string;\n  endAt?: string;\n};\n\n/**\n * Converts pagination date range to where clause date range format\n * @param dateRange - The date range from pagination\n * @param columnName - The timestamp column to filter on (defaults to 'createdAt')\n * @returns Object with the date range filter, or empty object if no date range\n */\nexport function buildDateRangeFilter(\n  dateRange?: PaginationArgs['dateRange'],\n  columnName: string = 'createdAt',\n): Record<string, DateRangeFilter> {\n  if (!dateRange?.start && !dateRange?.end) {\n    return {};\n  }\n\n  const filter: DateRangeFilter = {};\n\n  if (dateRange.start) {\n    filter.startAt = new Date(dateRange.start).toISOString();\n  }\n\n  if (dateRange.end) {\n    filter.endAt = new Date(dateRange.end).toISOString();\n  }\n\n  return { [columnName]: filter };\n}\n\n/**\n * Transforms SQL row data back to a typed object format\n * Reverses the transformations done in prepareStatement\n */\nexport function transformFromSqlRow<T>({\n  tableName,\n  sqlRow,\n}: {\n  tableName: TABLE_NAMES;\n  sqlRow: Record<string, any>;\n}): T {\n  const result: Record<string, any> = {};\n  const jsonColumns = new Set(\n    Object.keys(TABLE_SCHEMAS[tableName])\n      .filter(key => TABLE_SCHEMAS[tableName][key]!.type === 'jsonb')\n      .map(key => key),\n  );\n  const dateColumns = new Set(\n    Object.keys(TABLE_SCHEMAS[tableName])\n      .filter(key => TABLE_SCHEMAS[tableName][key]!.type === 'timestamp')\n      .map(key => key),\n  );\n\n  for (const [key, value] of Object.entries(sqlRow)) {\n    if (value === null || value === undefined) {\n      result[key] = value;\n      continue;\n    }\n\n    if (dateColumns.has(key) && typeof value === 'string') {\n      result[key] = new Date(value);\n      continue;\n    }\n\n    if (jsonColumns.has(key) && typeof value === 'string') {\n      result[key] = safelyParseJSON(value);\n      continue;\n    }\n\n    result[key] = value;\n  }\n\n  return result as T;\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { AI_SPAN_SCHEMA, ObservabilityStorage, TABLE_AI_SPANS } from '@mastra/core/storage';\nimport type {\n  AISpanRecord,\n  CreateAISpanRecord,\n  UpdateAISpanRecord,\n  AITraceRecord,\n  AITracesPaginatedArg,\n  PaginationInfo,\n} from '@mastra/core/storage';\nimport type { StoreOperationsLibSQL } from '../operations';\nimport { buildDateRangeFilter, prepareWhereClause, transformFromSqlRow } from '../utils';\n\nexport class ObservabilityLibSQL extends ObservabilityStorage {\n  private operations: StoreOperationsLibSQL;\n  constructor({ operations }: { operations: StoreOperationsLibSQL }) {\n    super();\n    this.operations = operations;\n  }\n\n  async createAISpan(span: CreateAISpanRecord): Promise<void> {\n    try {\n      // Explicitly set createdAt/updatedAt timestamps\n      const now = new Date().toISOString();\n      const record = {\n        ...span,\n        createdAt: now,\n        updatedAt: now,\n      };\n      return this.operations.insert({ tableName: TABLE_AI_SPANS, record });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_CREATE_AI_SPAN_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: {\n            spanId: span.spanId,\n            traceId: span.traceId,\n            spanType: span.spanType,\n            spanName: span.name,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  async getAITrace(traceId: string): Promise<AITraceRecord | null> {\n    try {\n      const spans = await this.operations.loadMany<AISpanRecord>({\n        tableName: TABLE_AI_SPANS,\n        whereClause: { sql: ' WHERE traceId = ?', args: [traceId] },\n        orderBy: 'startedAt DESC',\n      });\n\n      if (!spans || spans.length === 0) {\n        return null;\n      }\n\n      return {\n        traceId,\n        spans: spans.map(span => transformFromSqlRow<AISpanRecord>({ tableName: TABLE_AI_SPANS, sqlRow: span })),\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_AI_TRACE_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: {\n            traceId,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  async updateAISpan({\n    spanId,\n    traceId,\n    updates,\n  }: {\n    spanId: string;\n    traceId: string;\n    updates: Partial<UpdateAISpanRecord>;\n  }): Promise<void> {\n    try {\n      await this.operations.update({\n        tableName: TABLE_AI_SPANS,\n        keys: { spanId, traceId },\n        data: { ...updates, updatedAt: new Date().toISOString() },\n      });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_UPDATE_AI_SPAN_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: {\n            spanId,\n            traceId,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  async getAITracesPaginated({\n    filters,\n    pagination,\n  }: AITracesPaginatedArg): Promise<{ pagination: PaginationInfo; spans: AISpanRecord[] }> {\n    const page = pagination?.page ?? 0;\n    const perPage = pagination?.perPage ?? 10;\n    const { entityId, entityType, ...actualFilters } = filters || {};\n\n    const filtersWithDateRange: Record<string, any> = {\n      ...actualFilters,\n      ...buildDateRangeFilter(pagination?.dateRange, 'startedAt'),\n      parentSpanId: null,\n    };\n    const whereClause = prepareWhereClause(filtersWithDateRange, AI_SPAN_SCHEMA);\n\n    let actualWhereClause = whereClause.sql || '';\n\n    if (entityId && entityType) {\n      const statement = `name = ?`;\n      let name = '';\n      if (entityType === 'workflow') {\n        name = `workflow run: '${entityId}'`;\n      } else if (entityType === 'agent') {\n        name = `agent run: '${entityId}'`;\n      } else {\n        const error = new MastraError({\n          id: 'LIBSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: {\n            entityType,\n          },\n          text: `Cannot filter by entity type: ${entityType}`,\n        });\n        this.logger?.trackException(error);\n        throw error;\n      }\n\n      whereClause.args.push(name);\n\n      if (actualWhereClause) {\n        actualWhereClause += ` AND ${statement}`;\n      } else {\n        actualWhereClause += `WHERE ${statement}`;\n      }\n    }\n\n    const orderBy = 'startedAt DESC';\n\n    let count = 0;\n    try {\n      count = await this.operations.loadTotalCount({\n        tableName: TABLE_AI_SPANS,\n        whereClause: { sql: actualWhereClause, args: whereClause.args },\n      });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_AI_TRACES_PAGINATED_COUNT_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n        },\n        error,\n      );\n    }\n\n    if (count === 0) {\n      return {\n        pagination: {\n          total: 0,\n          page,\n          perPage,\n          hasMore: false,\n        },\n        spans: [],\n      };\n    }\n\n    try {\n      const spans = await this.operations.loadMany<AISpanRecord>({\n        tableName: TABLE_AI_SPANS,\n        whereClause: {\n          sql: actualWhereClause,\n          args: whereClause.args,\n        },\n        orderBy,\n        offset: page * perPage,\n        limit: perPage,\n      });\n\n      return {\n        pagination: {\n          total: count,\n          page,\n          perPage,\n          hasMore: spans.length === perPage,\n        },\n        spans: spans.map(span => transformFromSqlRow<AISpanRecord>({ tableName: TABLE_AI_SPANS, sqlRow: span })),\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n        },\n        error,\n      );\n    }\n  }\n\n  async batchCreateAISpans(args: { records: CreateAISpanRecord[] }): Promise<void> {\n    try {\n      // Use single timestamp for all records in the batch\n      const now = new Date().toISOString();\n      return this.operations.batchInsert({\n        tableName: TABLE_AI_SPANS,\n        records: args.records.map(record => ({\n          ...record,\n          createdAt: now,\n          updatedAt: now,\n        })),\n      });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_BATCH_CREATE_AI_SPANS_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n        },\n        error,\n      );\n    }\n  }\n\n  async batchUpdateAISpans(args: {\n    records: {\n      traceId: string;\n      spanId: string;\n      updates: Partial<UpdateAISpanRecord>;\n    }[];\n  }): Promise<void> {\n    try {\n      return this.operations.batchUpdate({\n        tableName: TABLE_AI_SPANS,\n        updates: args.records.map(record => ({\n          keys: { spanId: record.spanId, traceId: record.traceId },\n          data: { ...record.updates, updatedAt: new Date().toISOString() },\n        })),\n      });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_BATCH_UPDATE_AI_SPANS_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n        },\n        error,\n      );\n    }\n  }\n\n  async batchDeleteAITraces(args: { traceIds: string[] }): Promise<void> {\n    try {\n      const keys = args.traceIds.map(traceId => ({ traceId }));\n      return this.operations.batchDelete({\n        tableName: TABLE_AI_SPANS,\n        keys,\n      });\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_BATCH_DELETE_AI_TRACES_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n        },\n        error,\n      );\n    }\n  }\n}\n","import type { Client, InValue } from '@libsql/client';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { TABLE_WORKFLOW_SNAPSHOT, StoreOperations, TABLE_AI_SPANS } from '@mastra/core/storage';\nimport type { StorageColumn, TABLE_NAMES } from '@mastra/core/storage';\nimport { parseSqlIdentifier } from '@mastra/core/utils';\nimport {\n  createExecuteWriteOperationWithRetry,\n  prepareDeleteStatement,\n  prepareStatement,\n  prepareUpdateStatement,\n} from '../utils';\n\nexport class StoreOperationsLibSQL extends StoreOperations {\n  private client: Client;\n  /**\n   * Maximum number of retries for write operations if an SQLITE_BUSY error occurs.\n   * @default 5\n   */\n  maxRetries: number;\n  /**\n   * Initial backoff time in milliseconds for retrying write operations on SQLITE_BUSY.\n   * The backoff time will double with each retry (exponential backoff).\n   * @default 100\n   */\n  initialBackoffMs: number;\n\n  constructor({\n    client,\n    maxRetries,\n    initialBackoffMs,\n  }: {\n    client: Client;\n    maxRetries?: number;\n    initialBackoffMs?: number;\n  }) {\n    super();\n    this.client = client;\n\n    this.maxRetries = maxRetries ?? 5;\n    this.initialBackoffMs = initialBackoffMs ?? 100;\n  }\n\n  async hasColumn(table: string, column: string): Promise<boolean> {\n    const result = await this.client.execute({\n      sql: `PRAGMA table_info(${table})`,\n    });\n    return (await result.rows)?.some((row: any) => row.name === column);\n  }\n\n  private getCreateTableSQL(tableName: TABLE_NAMES, schema: Record<string, StorageColumn>): string {\n    const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n    const columns = Object.entries(schema).map(([name, col]) => {\n      const parsedColumnName = parseSqlIdentifier(name, 'column name');\n      let type = col.type.toUpperCase();\n      if (type === 'TEXT') type = 'TEXT';\n      if (type === 'TIMESTAMP') type = 'TEXT'; // Store timestamps as ISO strings\n      // if (type === 'BIGINT') type = 'INTEGER';\n\n      const nullable = col.nullable ? '' : 'NOT NULL';\n      const primaryKey = col.primaryKey ? 'PRIMARY KEY' : '';\n\n      return `${parsedColumnName} ${type} ${nullable} ${primaryKey}`.trim();\n    });\n\n    // For workflow_snapshot table, create a composite primary key\n    if (tableName === TABLE_WORKFLOW_SNAPSHOT) {\n      const stmnt = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (\n                    ${columns.join(',\\n')},\n                    PRIMARY KEY (workflow_name, run_id)\n                )`;\n      return stmnt;\n    }\n\n    if (tableName === TABLE_AI_SPANS) {\n      const stmnt = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (\n                    ${columns.join(',\\n')},\n                    PRIMARY KEY (traceId, spanId)\n                )`;\n      return stmnt;\n    }\n\n    return `CREATE TABLE IF NOT EXISTS ${parsedTableName} (${columns.join(', ')})`;\n  }\n\n  async createTable({\n    tableName,\n    schema,\n  }: {\n    tableName: TABLE_NAMES;\n    schema: Record<string, StorageColumn>;\n  }): Promise<void> {\n    try {\n      this.logger.debug(`Creating database table`, { tableName, operation: 'schema init' });\n      const sql = this.getCreateTableSQL(tableName, schema);\n      await this.client.execute(sql);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_CREATE_TABLE_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  protected getSqlType(type: StorageColumn['type']): string {\n    switch (type) {\n      case 'bigint':\n        return 'INTEGER'; // SQLite uses INTEGER for all integer sizes\n      case 'jsonb':\n        return 'TEXT'; // Store JSON as TEXT in SQLite\n      default:\n        return super.getSqlType(type);\n    }\n  }\n\n  private async doInsert({\n    tableName,\n    record,\n  }: {\n    tableName: TABLE_NAMES;\n    record: Record<string, any>;\n  }): Promise<void> {\n    await this.client.execute(\n      prepareStatement({\n        tableName,\n        record,\n      }),\n    );\n  }\n\n  public insert(args: { tableName: TABLE_NAMES; record: Record<string, any> }): Promise<void> {\n    const executeWriteOperationWithRetry = createExecuteWriteOperationWithRetry({\n      logger: this.logger,\n      maxRetries: this.maxRetries,\n      initialBackoffMs: this.initialBackoffMs,\n    });\n    return executeWriteOperationWithRetry(() => this.doInsert(args), `insert into table ${args.tableName}`);\n  }\n\n  async load<R>({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, string> }): Promise<R | null> {\n    const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n\n    const parsedKeys = Object.keys(keys).map(key => parseSqlIdentifier(key, 'column name'));\n\n    const conditions = parsedKeys.map(key => `${key} = ?`).join(' AND ');\n    const values = Object.values(keys);\n\n    const result = await this.client.execute({\n      sql: `SELECT * FROM ${parsedTableName} WHERE ${conditions} ORDER BY createdAt DESC LIMIT 1`,\n      args: values,\n    });\n\n    if (!result.rows || result.rows.length === 0) {\n      return null;\n    }\n\n    const row = result.rows[0];\n    // Checks whether the string looks like a JSON object ({}) or array ([])\n    // If the string starts with { or [, it assumes it's JSON and parses it\n    // Otherwise, it just returns, preventing unintended number conversions\n    const parsed = Object.fromEntries(\n      Object.entries(row || {}).map(([k, v]) => {\n        try {\n          return [k, typeof v === 'string' ? (v.startsWith('{') || v.startsWith('[') ? JSON.parse(v) : v) : v];\n        } catch {\n          return [k, v];\n        }\n      }),\n    );\n\n    return parsed as R;\n  }\n\n  async loadMany<R>({\n    tableName,\n    whereClause,\n    orderBy,\n    offset,\n    limit,\n    args,\n  }: {\n    tableName: TABLE_NAMES;\n    whereClause?: { sql: string; args: InValue[] };\n    orderBy?: string;\n    offset?: number;\n    limit?: number;\n    args?: any[];\n  }): Promise<R[]> {\n    const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n\n    let statement = `SELECT * FROM ${parsedTableName}`;\n\n    if (whereClause?.sql) {\n      statement += `${whereClause.sql}`;\n    }\n\n    if (orderBy) {\n      statement += ` ORDER BY ${orderBy}`;\n    }\n\n    if (limit) {\n      statement += ` LIMIT ${limit}`;\n    }\n\n    if (offset) {\n      statement += ` OFFSET ${offset}`;\n    }\n\n    const result = await this.client.execute({\n      sql: statement,\n      args: [...(whereClause?.args ?? []), ...(args ?? [])],\n    });\n\n    return result.rows as R[];\n  }\n\n  async loadTotalCount({\n    tableName,\n    whereClause,\n  }: {\n    tableName: TABLE_NAMES;\n    whereClause?: { sql: string; args: InValue[] };\n  }): Promise<number> {\n    const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n\n    const statement = `SELECT COUNT(*) as count FROM ${parsedTableName} ${whereClause ? `${whereClause.sql}` : ''}`;\n\n    const result = await this.client.execute({\n      sql: statement,\n      args: whereClause?.args ?? [],\n    });\n\n    if (!result.rows || result.rows.length === 0) {\n      return 0;\n    }\n\n    return (result.rows[0]?.count as number) ?? 0;\n  }\n\n  public update(args: { tableName: TABLE_NAMES; keys: Record<string, any>; data: Record<string, any> }): Promise<void> {\n    const executeWriteOperationWithRetry = createExecuteWriteOperationWithRetry({\n      logger: this.logger,\n      maxRetries: this.maxRetries,\n      initialBackoffMs: this.initialBackoffMs,\n    });\n    return executeWriteOperationWithRetry(() => this.executeUpdate(args), `update table ${args.tableName}`);\n  }\n\n  private async executeUpdate({\n    tableName,\n    keys,\n    data,\n  }: {\n    tableName: TABLE_NAMES;\n    keys: Record<string, any>;\n    data: Record<string, any>;\n  }): Promise<void> {\n    await this.client.execute(prepareUpdateStatement({ tableName, updates: data, keys }));\n  }\n\n  private async doBatchInsert({\n    tableName,\n    records,\n  }: {\n    tableName: TABLE_NAMES;\n    records: Record<string, any>[];\n  }): Promise<void> {\n    if (records.length === 0) return;\n    const batchStatements = records.map(r => prepareStatement({ tableName, record: r }));\n    await this.client.batch(batchStatements, 'write');\n  }\n\n  public batchInsert(args: { tableName: TABLE_NAMES; records: Record<string, any>[] }): Promise<void> {\n    const executeWriteOperationWithRetry = createExecuteWriteOperationWithRetry({\n      logger: this.logger,\n      maxRetries: this.maxRetries,\n      initialBackoffMs: this.initialBackoffMs,\n    });\n\n    return executeWriteOperationWithRetry(\n      () => this.doBatchInsert(args),\n      `batch insert into table ${args.tableName}`,\n    ).catch(error => {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_BATCH_INSERT_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName: args.tableName,\n          },\n        },\n        error,\n      );\n    });\n  }\n\n  /**\n   * Public batch update method with retry logic\n   */\n  public batchUpdate(args: {\n    tableName: TABLE_NAMES;\n    updates: Array<{\n      keys: Record<string, any>;\n      data: Record<string, any>;\n    }>;\n  }): Promise<void> {\n    const executeWriteOperationWithRetry = createExecuteWriteOperationWithRetry({\n      logger: this.logger,\n      maxRetries: this.maxRetries,\n      initialBackoffMs: this.initialBackoffMs,\n    });\n\n    return executeWriteOperationWithRetry(\n      () => this.executeBatchUpdate(args),\n      `batch update in table ${args.tableName}`,\n    ).catch(error => {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_BATCH_UPDATE_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName: args.tableName,\n          },\n        },\n        error,\n      );\n    });\n  }\n\n  /**\n   * Updates multiple records in batch. Each record can be updated based on single or composite keys.\n   */\n  private async executeBatchUpdate({\n    tableName,\n    updates,\n  }: {\n    tableName: TABLE_NAMES;\n    updates: Array<{\n      keys: Record<string, any>;\n      data: Record<string, any>;\n    }>;\n  }): Promise<void> {\n    if (updates.length === 0) return;\n\n    const batchStatements = updates.map(({ keys, data }) =>\n      prepareUpdateStatement({\n        tableName,\n        updates: data,\n        keys,\n      }),\n    );\n\n    await this.client.batch(batchStatements, 'write');\n  }\n\n  /**\n   * Public batch delete method with retry logic\n   */\n  public batchDelete({ tableName, keys }: { tableName: TABLE_NAMES; keys: Array<Record<string, any>> }): Promise<void> {\n    const executeWriteOperationWithRetry = createExecuteWriteOperationWithRetry({\n      logger: this.logger,\n      maxRetries: this.maxRetries,\n      initialBackoffMs: this.initialBackoffMs,\n    });\n\n    return executeWriteOperationWithRetry(\n      () => this.executeBatchDelete({ tableName, keys }),\n      `batch delete from table ${tableName}`,\n    ).catch(error => {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_BATCH_DELETE_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName,\n          },\n        },\n        error,\n      );\n    });\n  }\n\n  /**\n   * Deletes multiple records in batch. Each record can be deleted based on single or composite keys.\n   */\n  private async executeBatchDelete({\n    tableName,\n    keys,\n  }: {\n    tableName: TABLE_NAMES;\n    keys: Array<Record<string, any>>;\n  }): Promise<void> {\n    if (keys.length === 0) return;\n\n    const batchStatements = keys.map(keyObj =>\n      prepareDeleteStatement({\n        tableName,\n        keys: keyObj,\n      }),\n    );\n\n    await this.client.batch(batchStatements, 'write');\n  }\n\n  /**\n   * Alters table schema to add columns if they don't exist\n   * @param tableName Name of the table\n   * @param schema Schema of the table\n   * @param ifNotExists Array of column names to add if they don't exist\n   */\n  async alterTable({\n    tableName,\n    schema,\n    ifNotExists,\n  }: {\n    tableName: TABLE_NAMES;\n    schema: Record<string, StorageColumn>;\n    ifNotExists: string[];\n  }): Promise<void> {\n    const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n\n    try {\n      // 1. Get existing columns using PRAGMA\n      const pragmaQuery = `PRAGMA table_info(${parsedTableName})`;\n      const result = await this.client.execute(pragmaQuery);\n      const existingColumnNames = new Set(result.rows.map((row: any) => row.name.toLowerCase()));\n\n      // 2. Add missing columns\n      for (const columnName of ifNotExists) {\n        if (!existingColumnNames.has(columnName.toLowerCase()) && schema[columnName]) {\n          const columnDef = schema[columnName];\n          const sqlType = this.getSqlType(columnDef.type); // ensure this exists or implement\n          const nullable = columnDef.nullable === false ? 'NOT NULL' : '';\n          // In SQLite, you must provide a DEFAULT if adding a NOT NULL column to a non-empty table\n          const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : '';\n          const alterSql =\n            `ALTER TABLE ${parsedTableName} ADD COLUMN \"${columnName}\" ${sqlType} ${nullable} ${defaultValue}`.trim();\n\n          await this.client.execute(alterSql);\n          this.logger?.debug?.(`Added column ${columnName} to table ${parsedTableName}`);\n        }\n      }\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_ALTER_TABLE_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName,\n          },\n        },\n        error,\n      );\n    }\n  }\n\n  async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {\n    const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n    try {\n      await this.client.execute(`DELETE FROM ${parsedTableName}`);\n    } catch (e) {\n      const mastraError = new MastraError(\n        {\n          id: 'LIBSQL_STORE_CLEAR_TABLE_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName,\n          },\n        },\n        e,\n      );\n      this.logger?.trackException?.(mastraError);\n      this.logger?.error?.(mastraError.toString());\n    }\n  }\n\n  async dropTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {\n    const parsedTableName = parseSqlIdentifier(tableName, 'table name');\n    try {\n      await this.client.execute(`DROP TABLE IF EXISTS ${parsedTableName}`);\n    } catch (e) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_DROP_TABLE_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n          details: {\n            tableName,\n          },\n        },\n        e,\n      );\n    }\n  }\n}\n","import type { Client, InValue } from '@libsql/client';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { saveScorePayloadSchema } from '@mastra/core/scores';\nimport type { ScoreRowData, ScoringSource, ValidatedSaveScorePayload } from '@mastra/core/scores';\nimport { TABLE_SCORERS, ScoresStorage, safelyParseJSON } from '@mastra/core/storage';\nimport type { PaginationInfo, StoragePagination } from '@mastra/core/storage';\nimport type { StoreOperationsLibSQL } from '../operations';\n\nexport class ScoresLibSQL extends ScoresStorage {\n  private operations: StoreOperationsLibSQL;\n  private client: Client;\n  constructor({ client, operations }: { client: Client; operations: StoreOperationsLibSQL }) {\n    super();\n    this.operations = operations;\n    this.client = client;\n  }\n\n  async getScoresByRunId({\n    runId,\n    pagination,\n  }: {\n    runId: string;\n    pagination: StoragePagination;\n  }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {\n    try {\n      const result = await this.client.execute({\n        sql: `SELECT * FROM ${TABLE_SCORERS} WHERE runId = ? ORDER BY createdAt DESC LIMIT ? OFFSET ?`,\n        args: [runId, pagination.perPage + 1, pagination.page * pagination.perPage],\n      });\n      return {\n        scores: result.rows?.slice(0, pagination.perPage).map(row => this.transformScoreRow(row)) ?? [],\n        pagination: {\n          total: result.rows?.length ?? 0,\n          page: pagination.page,\n          perPage: pagination.perPage,\n          hasMore: result.rows?.length > pagination.perPage,\n        },\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_SCORES_BY_RUN_ID_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  async getScoresByScorerId({\n    scorerId,\n    entityId,\n    entityType,\n    source,\n    pagination,\n  }: {\n    scorerId: string;\n    entityId?: string;\n    entityType?: string;\n    source?: ScoringSource;\n    pagination: StoragePagination;\n  }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {\n    try {\n      const conditions: string[] = [];\n      const queryParams: InValue[] = [];\n\n      if (scorerId) {\n        conditions.push(`scorerId = ?`);\n        queryParams.push(scorerId);\n      }\n\n      if (entityId) {\n        conditions.push(`entityId = ?`);\n        queryParams.push(entityId);\n      }\n\n      if (entityType) {\n        conditions.push(`entityType = ?`);\n        queryParams.push(entityType);\n      }\n\n      if (source) {\n        conditions.push(`source = ?`);\n        queryParams.push(source);\n      }\n\n      const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n\n      const result = await this.client.execute({\n        sql: `SELECT * FROM ${TABLE_SCORERS} ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`,\n        args: [...queryParams, pagination.perPage + 1, pagination.page * pagination.perPage],\n      });\n\n      return {\n        scores: result.rows?.slice(0, pagination.perPage).map(row => this.transformScoreRow(row)) ?? [],\n        pagination: {\n          total: result.rows?.length ?? 0,\n          page: pagination.page,\n          perPage: pagination.perPage,\n          hasMore: result.rows?.length > pagination.perPage,\n        },\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_SCORES_BY_SCORER_ID_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  private transformScoreRow(row: Record<string, any>): ScoreRowData {\n    const scorerValue = safelyParseJSON(row.scorer);\n    const inputValue = safelyParseJSON(row.input ?? '{}');\n    const outputValue = safelyParseJSON(row.output ?? '{}');\n    const additionalLLMContextValue = row.additionalLLMContext ? safelyParseJSON(row.additionalLLMContext) : null;\n    const runtimeContextValue = row.runtimeContext ? safelyParseJSON(row.runtimeContext) : null;\n    const metadataValue = row.metadata ? safelyParseJSON(row.metadata) : null;\n    const entityValue = row.entity ? safelyParseJSON(row.entity) : null;\n    const preprocessStepResultValue = row.preprocessStepResult ? safelyParseJSON(row.preprocessStepResult) : null;\n    const analyzeStepResultValue = row.analyzeStepResult ? safelyParseJSON(row.analyzeStepResult) : null;\n\n    return {\n      id: row.id,\n      traceId: row.traceId,\n      spanId: row.spanId,\n      runId: row.runId,\n      scorer: scorerValue,\n      score: row.score,\n      reason: row.reason,\n      preprocessStepResult: preprocessStepResultValue,\n      analyzeStepResult: analyzeStepResultValue,\n      analyzePrompt: row.analyzePrompt,\n      preprocessPrompt: row.preprocessPrompt,\n      generateScorePrompt: row.generateScorePrompt,\n      generateReasonPrompt: row.generateReasonPrompt,\n      metadata: metadataValue,\n      input: inputValue,\n      output: outputValue,\n      additionalContext: additionalLLMContextValue,\n      runtimeContext: runtimeContextValue,\n      entityType: row.entityType,\n      entity: entityValue,\n      entityId: row.entityId,\n      scorerId: row.scorerId,\n      source: row.source,\n      resourceId: row.resourceId,\n      threadId: row.threadId,\n      createdAt: row.createdAt,\n      updatedAt: row.updatedAt,\n    };\n  }\n\n  async getScoreById({ id }: { id: string }): Promise<ScoreRowData | null> {\n    const result = await this.client.execute({\n      sql: `SELECT * FROM ${TABLE_SCORERS} WHERE id = ?`,\n      args: [id],\n    });\n    return result.rows?.[0] ? this.transformScoreRow(result.rows[0]) : null;\n  }\n\n  async saveScore(score: Omit<ScoreRowData, 'id' | 'createdAt' | 'updatedAt'>): Promise<{ score: ScoreRowData }> {\n    let parsedScore: ValidatedSaveScorePayload;\n    try {\n      parsedScore = saveScorePayloadSchema.parse(score);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_SAVE_SCORE_FAILED_INVALID_SCORE_PAYLOAD',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.USER,\n          details: {\n            scorer: score.scorer.name,\n            entityId: score.entityId,\n            entityType: score.entityType,\n            traceId: score.traceId || '',\n            spanId: score.spanId || '',\n          },\n        },\n        error,\n      );\n    }\n\n    try {\n      const id = crypto.randomUUID();\n\n      await this.operations.insert({\n        tableName: TABLE_SCORERS,\n        record: {\n          id,\n          createdAt: new Date().toISOString(),\n          updatedAt: new Date().toISOString(),\n          ...parsedScore,\n        },\n      });\n\n      const scoreFromDb = await this.getScoreById({ id });\n      return { score: scoreFromDb! };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_SAVE_SCORE_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  async getScoresByEntityId({\n    entityId,\n    entityType,\n    pagination,\n  }: {\n    pagination: StoragePagination;\n    entityId: string;\n    entityType: string;\n  }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {\n    try {\n      const result = await this.client.execute({\n        sql: `SELECT * FROM ${TABLE_SCORERS} WHERE entityId = ? AND entityType = ? ORDER BY createdAt DESC LIMIT ? OFFSET ?`,\n        args: [entityId, entityType, pagination.perPage + 1, pagination.page * pagination.perPage],\n      });\n      return {\n        scores: result.rows?.slice(0, pagination.perPage).map(row => this.transformScoreRow(row)) ?? [],\n        pagination: {\n          total: result.rows?.length ?? 0,\n          page: pagination.page,\n          perPage: pagination.perPage,\n          hasMore: result.rows?.length > pagination.perPage,\n        },\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_SCORES_BY_ENTITY_ID_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  async getScoresBySpan({\n    traceId,\n    spanId,\n    pagination,\n  }: {\n    traceId: string;\n    spanId: string;\n    pagination: StoragePagination;\n  }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {\n    try {\n      const countSQLResult = await this.client.execute({\n        sql: `SELECT COUNT(*) as count FROM ${TABLE_SCORERS} WHERE traceId = ? AND spanId = ?`,\n        args: [traceId, spanId],\n      });\n\n      const total = Number(countSQLResult.rows?.[0]?.count ?? 0);\n\n      const result = await this.client.execute({\n        sql: `SELECT * FROM ${TABLE_SCORERS} WHERE traceId = ? AND spanId = ? ORDER BY createdAt DESC LIMIT ? OFFSET ?`,\n        args: [traceId, spanId, pagination.perPage + 1, pagination.page * pagination.perPage],\n      });\n\n      const hasMore = result.rows?.length > pagination.perPage;\n      const scores = result.rows?.slice(0, pagination.perPage).map(row => this.transformScoreRow(row)) ?? [];\n\n      return {\n        scores,\n        pagination: {\n          total,\n          page: pagination.page,\n          perPage: pagination.perPage,\n          hasMore,\n        },\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_SCORES_BY_SPAN_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n}\n","import type { Client, InValue } from '@libsql/client';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { TABLE_TRACES, TracesStorage, safelyParseJSON } from '@mastra/core/storage';\nimport type { StorageGetTracesArg, StorageGetTracesPaginatedArg, PaginationInfo } from '@mastra/core/storage';\nimport type { Trace } from '@mastra/core/telemetry';\nimport { parseSqlIdentifier } from '@mastra/core/utils';\nimport type { StoreOperationsLibSQL } from '../operations';\n\nexport class TracesLibSQL extends TracesStorage {\n  private client: Client;\n  private operations: StoreOperationsLibSQL;\n\n  constructor({ client, operations }: { client: Client; operations: StoreOperationsLibSQL }) {\n    super();\n    this.client = client;\n    this.operations = operations;\n  }\n\n  async getTraces(args: StorageGetTracesArg): Promise<Trace[]> {\n    if (args.fromDate || args.toDate) {\n      (args as any).dateRange = {\n        start: args.fromDate,\n        end: args.toDate,\n      };\n    }\n    try {\n      const result = await this.getTracesPaginated(args);\n      return result.traces;\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_TRACES_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  async getTracesPaginated(args: StorageGetTracesPaginatedArg): Promise<PaginationInfo & { traces: Trace[] }> {\n    const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;\n    const fromDate = dateRange?.start;\n    const toDate = dateRange?.end;\n    const currentOffset = page * perPage;\n\n    const queryArgs: InValue[] = [];\n    const conditions: string[] = [];\n\n    if (name) {\n      conditions.push('name LIKE ?');\n      queryArgs.push(`${name}%`);\n    }\n    if (scope) {\n      conditions.push('scope = ?');\n      queryArgs.push(scope);\n    }\n    if (attributes) {\n      Object.entries(attributes).forEach(([key, value]) => {\n        conditions.push(`json_extract(attributes, '$.${key}') = ?`);\n        queryArgs.push(value);\n      });\n    }\n    if (filters) {\n      Object.entries(filters).forEach(([key, value]) => {\n        conditions.push(`${parseSqlIdentifier(key, 'filter key')} = ?`);\n        queryArgs.push(value);\n      });\n    }\n    if (fromDate) {\n      conditions.push('createdAt >= ?');\n      queryArgs.push(fromDate.toISOString());\n    }\n    if (toDate) {\n      conditions.push('createdAt <= ?');\n      queryArgs.push(toDate.toISOString());\n    }\n\n    const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n\n    try {\n      const countResult = await this.client.execute({\n        sql: `SELECT COUNT(*) as count FROM ${TABLE_TRACES} ${whereClause}`,\n        args: queryArgs,\n      });\n      const total = Number(countResult.rows?.[0]?.count ?? 0);\n\n      if (total === 0) {\n        return {\n          traces: [],\n          total: 0,\n          page,\n          perPage,\n          hasMore: false,\n        };\n      }\n\n      const dataResult = await this.client.execute({\n        sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY \"startTime\" DESC LIMIT ? OFFSET ?`,\n        args: [...queryArgs, perPage, currentOffset],\n      });\n\n      const traces =\n        dataResult.rows?.map(\n          row =>\n            ({\n              id: row.id,\n              parentSpanId: row.parentSpanId,\n              traceId: row.traceId,\n              name: row.name,\n              scope: row.scope,\n              kind: row.kind,\n              status: safelyParseJSON(row.status),\n              events: safelyParseJSON(row.events),\n              links: safelyParseJSON(row.links),\n              attributes: safelyParseJSON(row.attributes),\n              startTime: row.startTime,\n              endTime: row.endTime,\n              other: safelyParseJSON(row.other),\n              createdAt: row.createdAt,\n            }) as Trace,\n        ) ?? [];\n\n      return {\n        traces,\n        total,\n        page,\n        perPage,\n        hasMore: currentOffset + traces.length < total,\n      };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_TRACES_PAGINATED_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  async batchTraceInsert({ records }: { records: Record<string, any>[] }): Promise<void> {\n    this.logger.debug('Batch inserting traces', { count: records.length });\n    await this.operations.batchInsert({\n      tableName: TABLE_TRACES,\n      records,\n    });\n  }\n}\n","import type { Client, InValue } from '@libsql/client';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport type { WorkflowRun, WorkflowRuns } from '@mastra/core/storage';\nimport { TABLE_WORKFLOW_SNAPSHOT, WorkflowsStorage } from '@mastra/core/storage';\nimport type { WorkflowRunState, StepResult } from '@mastra/core/workflows';\nimport type { StoreOperationsLibSQL } from '../operations';\n\nfunction parseWorkflowRun(row: Record<string, 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      // If parsing fails, return the raw snapshot string\n      console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);\n    }\n  }\n  return {\n    workflowName: row.workflow_name as string,\n    runId: row.run_id as string,\n    snapshot: parsedSnapshot,\n    resourceId: row.resourceId as string,\n    createdAt: new Date(row.createdAt as string),\n    updatedAt: new Date(row.updatedAt as string),\n  };\n}\n\nexport class WorkflowsLibSQL extends WorkflowsStorage {\n  operations: StoreOperationsLibSQL;\n  client: Client;\n  private readonly maxRetries: number;\n  private readonly initialBackoffMs: number;\n\n  constructor({\n    operations,\n    client,\n    maxRetries = 5,\n    initialBackoffMs = 500,\n  }: {\n    operations: StoreOperationsLibSQL;\n    client: Client;\n    maxRetries?: number;\n    initialBackoffMs?: number;\n  }) {\n    super();\n    this.operations = operations;\n    this.client = client;\n    this.maxRetries = maxRetries;\n    this.initialBackoffMs = initialBackoffMs;\n\n    // Set PRAGMA settings to help with database locks\n    // Note: This is async but we can't await in constructor, so we'll handle it as a fire-and-forget\n    this.setupPragmaSettings().catch(err =>\n      this.logger.warn('LibSQL Workflows: Failed to setup PRAGMA settings.', err),\n    );\n  }\n\n  private async setupPragmaSettings() {\n    try {\n      // Set busy timeout to wait longer before returning busy errors\n      await this.client.execute('PRAGMA busy_timeout = 10000;');\n      this.logger.debug('LibSQL Workflows: PRAGMA busy_timeout=10000 set.');\n\n      // Enable WAL mode for better concurrency (if supported)\n      try {\n        await this.client.execute('PRAGMA journal_mode = WAL;');\n        this.logger.debug('LibSQL Workflows: PRAGMA journal_mode=WAL set.');\n      } catch {\n        this.logger.debug('LibSQL Workflows: WAL mode not supported, using default journal mode.');\n      }\n\n      // Set synchronous mode for better durability vs performance trade-off\n      try {\n        await this.client.execute('PRAGMA synchronous = NORMAL;');\n        this.logger.debug('LibSQL Workflows: PRAGMA synchronous=NORMAL set.');\n      } catch {\n        this.logger.debug('LibSQL Workflows: Failed to set synchronous mode.');\n      }\n    } catch (err) {\n      this.logger.warn('LibSQL Workflows: Failed to set PRAGMA settings.', err);\n    }\n  }\n\n  private async executeWithRetry<T>(operation: () => Promise<T>): Promise<T> {\n    let attempts = 0;\n    let backoff = this.initialBackoffMs;\n\n    while (attempts < this.maxRetries) {\n      try {\n        return await operation();\n      } catch (error: any) {\n        // Log the error details for debugging\n        this.logger.debug('LibSQL Workflows: Error caught in retry loop', {\n          errorType: error.constructor.name,\n          errorCode: error.code,\n          errorMessage: error.message,\n          attempts,\n          maxRetries: this.maxRetries,\n        });\n\n        // Check for various database lock/busy conditions\n        const isLockError =\n          error.code === 'SQLITE_BUSY' ||\n          error.code === 'SQLITE_LOCKED' ||\n          error.message?.toLowerCase().includes('database is locked') ||\n          error.message?.toLowerCase().includes('database table is locked') ||\n          error.message?.toLowerCase().includes('table is locked') ||\n          (error.constructor.name === 'SqliteError' && error.message?.toLowerCase().includes('locked'));\n\n        if (isLockError) {\n          attempts++;\n          if (attempts >= this.maxRetries) {\n            this.logger.error(\n              `LibSQL Workflows: Operation failed after ${this.maxRetries} attempts due to database lock: ${error.message}`,\n              { error, attempts, maxRetries: this.maxRetries },\n            );\n            throw error;\n          }\n          this.logger.warn(\n            `LibSQL Workflows: Attempt ${attempts} failed due to database lock. Retrying in ${backoff}ms...`,\n            { errorMessage: error.message, attempts, backoff, maxRetries: this.maxRetries },\n          );\n          await new Promise(resolve => setTimeout(resolve, backoff));\n          backoff *= 2;\n        } else {\n          // Not a lock error, re-throw immediately\n          this.logger.error('LibSQL Workflows: Non-lock error occurred, not retrying', { error });\n          throw error;\n        }\n      }\n    }\n    throw new Error('LibSQL Workflows: Max retries reached, but no error was re-thrown from the loop.');\n  }\n\n  async updateWorkflowResults({\n    workflowName,\n    runId,\n    stepId,\n    result,\n    runtimeContext,\n  }: {\n    workflowName: string;\n    runId: string;\n    stepId: string;\n    result: StepResult<any, any, any, any>;\n    runtimeContext: Record<string, any>;\n  }): Promise<Record<string, StepResult<any, any, any, any>>> {\n    return this.executeWithRetry(async () => {\n      // Use a transaction to ensure atomicity\n      const tx = await this.client.transaction('write');\n      try {\n        // Load existing snapshot within transaction\n        const existingSnapshotResult = await tx.execute({\n          sql: `SELECT snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,\n          args: [workflowName, runId],\n        });\n\n        let snapshot: WorkflowRunState;\n        if (!existingSnapshotResult.rows?.[0]) {\n          // Create new snapshot if none exists\n          snapshot = {\n            context: {},\n            activePaths: [],\n            timestamp: Date.now(),\n            suspendedPaths: {},\n            resumeLabels: {},\n            serializedStepGraph: [],\n            value: {},\n            waitingPaths: {},\n            status: 'pending',\n            runId: runId,\n            runtimeContext: {},\n          } as WorkflowRunState;\n        } else {\n          // Parse existing snapshot\n          const existingSnapshot = existingSnapshotResult.rows[0].snapshot;\n          snapshot = typeof existingSnapshot === 'string' ? JSON.parse(existingSnapshot) : existingSnapshot;\n        }\n\n        // Merge the new step result and runtime context\n        snapshot.context[stepId] = result;\n        snapshot.runtimeContext = { ...snapshot.runtimeContext, ...runtimeContext };\n\n        // Update the snapshot within the same transaction\n        await tx.execute({\n          sql: `UPDATE ${TABLE_WORKFLOW_SNAPSHOT} SET snapshot = ? WHERE workflow_name = ? AND run_id = ?`,\n          args: [JSON.stringify(snapshot), workflowName, runId],\n        });\n\n        await tx.commit();\n        return snapshot.context;\n      } catch (error) {\n        if (!tx.closed) {\n          await tx.rollback();\n        }\n        throw error;\n      }\n    });\n  }\n\n  async updateWorkflowState({\n    workflowName,\n    runId,\n    opts,\n  }: {\n    workflowName: string;\n    runId: string;\n    opts: {\n      status: string;\n      result?: StepResult<any, any, any, any>;\n      error?: string;\n      suspendedPaths?: Record<string, number[]>;\n      waitingPaths?: Record<string, number[]>;\n    };\n  }): Promise<WorkflowRunState | undefined> {\n    return this.executeWithRetry(async () => {\n      // Use a transaction to ensure atomicity\n      const tx = await this.client.transaction('write');\n      try {\n        // Load existing snapshot within transaction\n        const existingSnapshotResult = await tx.execute({\n          sql: `SELECT snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,\n          args: [workflowName, runId],\n        });\n\n        if (!existingSnapshotResult.rows?.[0]) {\n          await tx.rollback();\n          return undefined;\n        }\n\n        // Parse existing snapshot\n        const existingSnapshot = existingSnapshotResult.rows[0].snapshot;\n        const snapshot = typeof existingSnapshot === 'string' ? JSON.parse(existingSnapshot) : existingSnapshot;\n\n        if (!snapshot || !snapshot?.context) {\n          await tx.rollback();\n          throw new Error(`Snapshot not found for runId ${runId}`);\n        }\n\n        // Merge the new options with the existing snapshot\n        const updatedSnapshot = { ...snapshot, ...opts };\n\n        // Update the snapshot within the same transaction\n        await tx.execute({\n          sql: `UPDATE ${TABLE_WORKFLOW_SNAPSHOT} SET snapshot = ? WHERE workflow_name = ? AND run_id = ?`,\n          args: [JSON.stringify(updatedSnapshot), workflowName, runId],\n        });\n\n        await tx.commit();\n        return updatedSnapshot;\n      } catch (error) {\n        if (!tx.closed) {\n          await tx.rollback();\n        }\n        throw error;\n      }\n    });\n  }\n\n  async persistWorkflowSnapshot({\n    workflowName,\n    runId,\n    resourceId,\n    snapshot,\n  }: {\n    workflowName: string;\n    runId: string;\n    resourceId?: string;\n    snapshot: WorkflowRunState;\n  }) {\n    const data = {\n      workflow_name: workflowName,\n      run_id: runId,\n      resourceId,\n      snapshot,\n      createdAt: new Date(),\n      updatedAt: new Date(),\n    };\n\n    this.logger.debug('Persisting workflow snapshot', { workflowName, runId, data });\n    await this.operations.insert({\n      tableName: TABLE_WORKFLOW_SNAPSHOT,\n      record: data,\n    });\n  }\n\n  async loadWorkflowSnapshot({\n    workflowName,\n    runId,\n  }: {\n    workflowName: string;\n    runId: string;\n  }): Promise<WorkflowRunState | null> {\n    this.logger.debug('Loading workflow snapshot', { workflowName, runId });\n    const d = await this.operations.load<{ snapshot: WorkflowRunState }>({\n      tableName: TABLE_WORKFLOW_SNAPSHOT,\n      keys: { workflow_name: workflowName, run_id: runId },\n    });\n\n    return d ? d.snapshot : null;\n  }\n\n  async getWorkflowRunById({\n    runId,\n    workflowName,\n  }: {\n    runId: string;\n    workflowName?: string;\n  }): Promise<WorkflowRun | null> {\n    const conditions: string[] = [];\n    const args: (string | number)[] = [];\n\n    if (runId) {\n      conditions.push('run_id = ?');\n      args.push(runId);\n    }\n\n    if (workflowName) {\n      conditions.push('workflow_name = ?');\n      args.push(workflowName);\n    }\n\n    const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n\n    try {\n      const result = await this.client.execute({\n        sql: `SELECT * FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause} ORDER BY createdAt DESC LIMIT 1`,\n        args,\n      });\n\n      if (!result.rows?.[0]) {\n        return null;\n      }\n\n      return parseWorkflowRun(result.rows[0]);\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n\n  async getWorkflowRuns({\n    workflowName,\n    fromDate,\n    toDate,\n    limit,\n    offset,\n    resourceId,\n  }: {\n    workflowName?: string;\n    fromDate?: Date;\n    toDate?: Date;\n    limit?: number;\n    offset?: number;\n    resourceId?: string;\n  } = {}): Promise<WorkflowRuns> {\n    try {\n      const conditions: string[] = [];\n      const args: InValue[] = [];\n\n      if (workflowName) {\n        conditions.push('workflow_name = ?');\n        args.push(workflowName);\n      }\n\n      if (fromDate) {\n        conditions.push('createdAt >= ?');\n        args.push(fromDate.toISOString());\n      }\n\n      if (toDate) {\n        conditions.push('createdAt <= ?');\n        args.push(toDate.toISOString());\n      }\n\n      if (resourceId) {\n        const hasResourceId = await this.operations.hasColumn(TABLE_WORKFLOW_SNAPSHOT, 'resourceId');\n        if (hasResourceId) {\n          conditions.push('resourceId = ?');\n          args.push(resourceId);\n        } else {\n          console.warn(`[${TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);\n        }\n      }\n\n      const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n\n      let total = 0;\n      // Only get total count when using pagination\n      if (limit !== undefined && offset !== undefined) {\n        const countResult = await this.client.execute({\n          sql: `SELECT COUNT(*) as count FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,\n          args,\n        });\n        total = Number(countResult.rows?.[0]?.count ?? 0);\n      }\n\n      // Get results\n      const result = await this.client.execute({\n        sql: `SELECT * FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause} ORDER BY createdAt DESC${limit !== undefined && offset !== undefined ? ` LIMIT ? OFFSET ?` : ''}`,\n        args: limit !== undefined && offset !== undefined ? [...args, limit, offset] : args,\n      });\n\n      const runs = (result.rows || []).map(row => parseWorkflowRun(row));\n\n      // Use runs.length as total when not paginating\n      return { runs, total: total || runs.length };\n    } catch (error) {\n      throw new MastraError(\n        {\n          id: 'LIBSQL_STORE_GET_WORKFLOW_RUNS_FAILED',\n          domain: ErrorDomain.STORAGE,\n          category: ErrorCategory.THIRD_PARTY,\n        },\n        error,\n      );\n    }\n  }\n}\n","import { createClient } from '@libsql/client';\nimport type { Client } from '@libsql/client';\nimport type { MastraMessageContentV2, MastraMessageV2 } from '@mastra/core/agent';\nimport type { MastraMessageV1, StorageThreadType } from '@mastra/core/memory';\nimport type { ScoreRowData, ScoringSource } from '@mastra/core/scores';\nimport { MastraStorage } from '@mastra/core/storage';\nimport type {\n  EvalRow,\n  PaginationArgs,\n  PaginationInfo,\n  StorageColumn,\n  StoragePagination,\n  StorageGetMessagesArg,\n  StorageResourceType,\n  TABLE_NAMES,\n  WorkflowRun,\n  WorkflowRuns,\n  StorageGetTracesArg,\n  StorageDomains,\n  ThreadSortOptions,\n  AISpanRecord,\n  AITraceRecord,\n  AITracesPaginatedArg,\n} from '@mastra/core/storage';\n\nimport type { Trace } from '@mastra/core/telemetry';\nimport type { StepResult, WorkflowRunState } from '@mastra/core/workflows';\nimport { LegacyEvalsLibSQL } from './domains/legacy-evals';\nimport { MemoryLibSQL } from './domains/memory';\nimport { ObservabilityLibSQL } from './domains/observability';\nimport { StoreOperationsLibSQL } from './domains/operations';\nimport { ScoresLibSQL } from './domains/scores';\nimport { TracesLibSQL } from './domains/traces';\nimport { WorkflowsLibSQL } from './domains/workflows';\n\nexport type LibSQLConfig =\n  | {\n      url: string;\n      authToken?: string;\n      /**\n       * Maximum number of retries for write operations if an SQLITE_BUSY error occurs.\n       * @default 5\n       */\n      maxRetries?: number;\n      /**\n       * Initial backoff time in milliseconds for retrying write operations on SQLITE_BUSY.\n       * The backoff time will double with each retry (exponential backoff).\n       * @default 100\n       */\n      initialBackoffMs?: number;\n    }\n  | {\n      client: Client;\n      maxRetries?: number;\n      initialBackoffMs?: number;\n    };\n\nexport class LibSQLStore extends MastraStorage {\n  private client: Client;\n  private readonly maxRetries: number;\n  private readonly initialBackoffMs: number;\n\n  stores: StorageDomains;\n\n  constructor(config: LibSQLConfig) {\n    super({ name: `LibSQLStore` });\n\n    this.maxRetries = config.maxRetries ?? 5;\n    this.initialBackoffMs = config.initialBackoffMs ?? 100;\n\n    if ('url' in config) {\n      // need to re-init every time for in memory dbs or the tables might not exist\n      if (config.url.endsWith(':memory:')) {\n        this.shouldCacheInit = false;\n      }\n\n      this.client = createClient({\n        url: config.url,\n        ...(config.authToken ? { authToken: config.authToken } : {}),\n      });\n\n      // Set PRAGMAs for better concurrency, especially for file-based databases\n      if (config.url.startsWith('file:') || config.url.includes(':memory:')) {\n        this.client\n          .execute('PRAGMA journal_mode=WAL;')\n          .then(() => this.logger.debug('LibSQLStore: PRAGMA journal_mode=WAL set.'))\n          .catch(err => this.logger.warn('LibSQLStore: Failed to set PRAGMA journal_mode=WAL.', err));\n        this.client\n          .execute('PRAGMA busy_timeout = 5000;') // 5 seconds\n          .then(() => this.logger.debug('LibSQLStore: PRAGMA busy_timeout=5000 set.'))\n          .catch(err => this.logger.warn('LibSQLStore: Failed to set PRAGMA busy_timeout.', err));\n      }\n    } else {\n      this.client = config.client;\n    }\n\n    const operations = new StoreOperationsLibSQL({\n      client: this.client,\n      maxRetries: this.maxRetries,\n      initialBackoffMs: this.initialBackoffMs,\n    });\n\n    const scores = new ScoresLibSQL({ client: this.client, operations });\n    const traces = new TracesLibSQL({ client: this.client, operations });\n    const workflows = new WorkflowsLibSQL({ client: this.client, operations });\n    const memory = new MemoryLibSQL({ client: this.client, operations });\n    const legacyEvals = new LegacyEvalsLibSQL({ client: this.client });\n    const observability = new ObservabilityLibSQL({ operations });\n\n    this.stores = {\n      operations,\n      scores,\n      traces,\n      workflows,\n      memory,\n      legacyEvals,\n      observability,\n    };\n  }\n\n  public get supports() {\n    return {\n      selectByIncludeResourceScope: true,\n      resourceWorkingMemory: true,\n      hasColumn: true,\n      createTable: true,\n      deleteMessages: true,\n      aiTracing: true,\n      getScoresBySpan: true,\n    };\n  }\n\n  async createTable({\n    tableName,\n    schema,\n  }: {\n    tableName: TABLE_NAMES;\n    schema: Record<string, StorageColumn>;\n  }): Promise<void> {\n    await this.stores.operations.createTable({ tableName, schema });\n  }\n\n  /**\n   * Alters table schema to add columns if they don't exist\n   * @param tableName Name of the table\n   * @param schema Schema of the table\n   * @param ifNotExists Array of column names to add if they don't exist\n   */\n  async alterTable({\n    tableName,\n    schema,\n    ifNotExists,\n  }: {\n    tableName: TABLE_NAMES;\n    schema: Record<string, StorageColumn>;\n    ifNotExists: string[];\n  }): Promise<void> {\n    await this.stores.operations.alterTable({ tableName, schema, ifNotExists });\n  }\n\n  async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {\n    await this.stores.operations.clearTable({ tableName });\n  }\n\n  async dropTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {\n    await this.stores.operations.dropTable({ tableName });\n  }\n\n  public insert(args: { tableName: TABLE_NAMES; record: Record<string, any> }): Promise<void> {\n    return this.stores.operations.insert(args);\n  }\n\n  public batchInsert(args: { tableName: TABLE_NAMES; records: Record<string, any>[] }): Promise<void> {\n    return this.stores.operations.batchInsert(args);\n  }\n\n  async load<R>({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, string> }): Promise<R | null> {\n    return this.stores.operations.load({ tableName, keys });\n  }\n\n  async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {\n    return this.stores.memory.getThreadById({ threadId });\n  }\n\n  /**\n   * @deprecated use getThreadsByResourceIdPaginated instead for paginated results.\n   */\n  public async getThreadsByResourceId(args: { resourceId: string } & ThreadSortOptions): Promise<StorageThreadType[]> {\n    return this.stores.memory.getThreadsByResourceId(args);\n  }\n\n  public async getThreadsByResourceIdPaginated(\n    args: {\n      resourceId: string;\n      page: number;\n      perPage: number;\n    } & ThreadSortOptions,\n  ): Promise<PaginationInfo & { threads: StorageThreadType[] }> {\n    return this.stores.memory.getThreadsByResourceIdPaginated(args);\n  }\n\n  async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {\n    return this.stores.memory.saveThread({ thread });\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    return this.stores.memory.updateThread({ id, title, metadata });\n  }\n\n  async deleteThread({ threadId }: { threadId: string }): Promise<void> {\n    return this.stores.memory.deleteThread({ threadId });\n  }\n\n  /**\n   * @deprecated use getMessagesPaginated instead for paginated results.\n   */\n  public async getMessages(args: StorageGetMessagesArg & { format?: 'v1' }): Promise<MastraMessageV1[]>;\n  public async getMessages(args: StorageGetMessagesArg & { format: 'v2' }): Promise<MastraMessageV2[]>;\n  public async getMessages({\n    threadId,\n    selectBy,\n    format,\n  }: StorageGetMessagesArg & {\n    format?: 'v1' | 'v2';\n  }): Promise<MastraMessageV1[] | MastraMessageV2[]> {\n    return this.stores.memory.getMessages({ threadId, selectBy, format });\n  }\n\n  async getMessagesById({ messageIds, format }: { messageIds: string[]; format: 'v1' }): Promise<MastraMessageV1[]>;\n  async getMessagesById({ messageIds, format }: { messageIds: string[]; format?: 'v2' }): Promise<MastraMessageV2[]>;\n  async getMessagesById({\n    messageIds,\n    format,\n  }: {\n    messageIds: string[];\n    format?: 'v1' | 'v2';\n  }): Promise<MastraMessageV1[] | MastraMessageV2[]> {\n    return this.stores.memory.getMessagesById({ messageIds, format });\n  }\n\n  public async getMessagesPaginated(\n    args: StorageGetMessagesArg & {\n      format?: 'v1' | 'v2';\n    },\n  ): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {\n    return this.stores.memory.getMessagesPaginated(args);\n  }\n\n  async saveMessages(args: { messages: MastraMessageV1[]; format?: undefined | 'v1' }): Promise<MastraMessageV1[]>;\n  async saveMessages(args: { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[]>;\n  async saveMessages(\n    args: { messages: MastraMessageV1[]; format?: undefined | 'v1' } | { messages: MastraMessageV2[]; format: 'v2' },\n  ): Promise<MastraMessageV2[] | MastraMessageV1[]> {\n    return this.stores.memory.saveMessages(args);\n  }\n\n  async updateMessages({\n    messages,\n  }: {\n    messages: (Partial<Omit<MastraMessageV2, 'createdAt'>> & {\n      id: string;\n      content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };\n    })[];\n  }): Promise<MastraMessageV2[]> {\n    return this.stores.memory.updateMessages({ messages });\n  }\n\n  async deleteMessages(messageIds: string[]): Promise<void> {\n    return this.stores.memory.deleteMessages(messageIds);\n  }\n\n  /** @deprecated use getEvals instead */\n  async getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]> {\n    return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);\n  }\n\n  async getEvals(\n    options: {\n      agentName?: string;\n      type?: 'test' | 'live';\n    } & PaginationArgs = {},\n  ): Promise<PaginationInfo & { evals: EvalRow[] }> {\n    return this.stores.legacyEvals.getEvals(options);\n  }\n\n  async getScoreById({ id }: { id: string }): Promise<ScoreRowData | null> {\n    return this.stores.scores.getScoreById({ id });\n  }\n\n  async saveScore(score: Omit<ScoreRowData, 'id' | 'createdAt' | 'updatedAt'>): Promise<{ score: ScoreRowData }> {\n    return this.stores.scores.saveScore(score);\n  }\n\n  async getScoresByScorerId({\n    scorerId,\n    entityId,\n    entityType,\n    source,\n    pagination,\n  }: {\n    scorerId: string;\n    entityId?: string;\n    entityType?: string;\n    source?: ScoringSource;\n    pagination: StoragePagination;\n  }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {\n    return this.stores.scores.getScoresByScorerId({ scorerId, entityId, entityType, source, pagination });\n  }\n\n  async getScoresByRunId({\n    runId,\n    pagination,\n  }: {\n    runId: string;\n    pagination: StoragePagination;\n  }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {\n    return this.stores.scores.getScoresByRunId({ runId, pagination });\n  }\n\n  async getScoresByEntityId({\n    entityId,\n    entityType,\n    pagination,\n  }: {\n    pagination: StoragePagination;\n    entityId: string;\n    entityType: string;\n  }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {\n    return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });\n  }\n\n  /**\n   * TRACES\n   */\n\n  /**\n   * @deprecated use getTracesPaginated instead.\n   */\n  async getTraces(args: StorageGetTracesArg): Promise<Trace[]> {\n    return this.stores.traces.getTraces(args);\n  }\n\n  async getTracesPaginated(args: StorageGetTracesArg): Promise<PaginationInfo & { traces: Trace[] }> {\n    return this.stores.traces.getTracesPaginated(args);\n  }\n\n  async batchTraceInsert(args: { records: Record<string, any>[] }): Promise<void> {\n    return this.stores.traces.batchTraceInsert(args);\n  }\n\n  /**\n   * WORKFLOWS\n   */\n\n  async updateWorkflowResults({\n    workflowName,\n    runId,\n    stepId,\n    result,\n    runtimeContext,\n  }: {\n    workflowName: string;\n    runId: string;\n    stepId: string;\n    result: StepResult<any, any, any, any>;\n    runtimeContext: Record<string, any>;\n  }): Promise<Record<string, StepResult<any, any, any, any>>> {\n    return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });\n  }\n\n  async updateWorkflowState({\n    workflowName,\n    runId,\n    opts,\n  }: {\n    workflowName: string;\n    runId: string;\n    opts: {\n      status: string;\n      result?: StepResult<any, any, any, any>;\n      error?: string;\n      suspendedPaths?: Record<string, number[]>;\n      waitingPaths?: Record<string, number[]>;\n    };\n  }): Promise<WorkflowRunState | undefined> {\n    return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });\n  }\n\n  async persistWorkflowSnapshot({\n    workflowName,\n    runId,\n    resourceId,\n    snapshot,\n  }: {\n    workflowName: string;\n    runId: string;\n    resourceId?: string;\n    snapshot: WorkflowRunState;\n  }): Promise<void> {\n    return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });\n  }\n\n  async loadWorkflowSnapshot({\n    workflowName,\n    runId,\n  }: {\n    workflowName: string;\n    runId: string;\n  }): Promise<WorkflowRunState | null> {\n    return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });\n  }\n\n  async getWorkflowRuns({\n    workflowName,\n    fromDate,\n    toDate,\n    limit,\n    offset,\n    resourceId,\n  }: {\n    workflowName?: string;\n    fromDate?: Date;\n    toDate?: Date;\n    limit?: number;\n    offset?: number;\n    resourceId?: string;\n  } = {}): Promise<WorkflowRuns> {\n    return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });\n  }\n\n  async getWorkflowRunById({\n    runId,\n    workflowName,\n  }: {\n    runId: string;\n    workflowName?: string;\n  }): Promise<WorkflowRun | null> {\n    return this.stores.workflows.getWorkflowRunById({ runId, workflowName });\n  }\n\n  async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {\n    return this.stores.memory.getResourceById({ resourceId });\n  }\n\n  async saveResource({ resource }: { resource: StorageResourceType }): Promise<StorageResourceType> {\n    return this.stores.memory.saveResource({ resource });\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    return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });\n  }\n\n  async createAISpan(span: AISpanRecord): Promise<void> {\n    return this.stores.observability!.createAISpan(span);\n  }\n\n  async updateAISpan(params: {\n    spanId: string;\n    traceId: string;\n    updates: Partial<Omit<AISpanRecord, 'spanId' | 'traceId'>>;\n  }): Promise<void> {\n    return this.stores.observability!.updateAISpan(params);\n  }\n\n  async getAITrace(traceId: string): Promise<AITraceRecord | null> {\n    return this.stores.observability!.getAITrace(traceId);\n  }\n\n  async getAITracesPaginated(\n    args: AITracesPaginatedArg,\n  ): Promise<{ pagination: PaginationInfo; spans: AISpanRecord[] }> {\n    return this.stores.observability!.getAITracesPaginated(args);\n  }\n\n  async getScoresBySpan({\n    traceId,\n    spanId,\n    pagination,\n  }: {\n    traceId: string;\n    spanId: string;\n    pagination: StoragePagination;\n  }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {\n    return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination });\n  }\n\n  async batchCreateAISpans(args: { records: AISpanRecord[] }): Promise<void> {\n    return this.stores.observability!.batchCreateAISpans(args);\n  }\n\n  async batchUpdateAISpans(args: {\n    records: { traceId: string; spanId: string; updates: Partial<Omit<AISpanRecord, 'spanId' | 'traceId'>> }[];\n  }): Promise<void> {\n    return this.stores.observability!.batchUpdateAISpans(args);\n  }\n}\n\nexport { LibSQLStore as DefaultStorage };\n","/**\n * Vector store specific prompt that details supported operators and examples.\n * This prompt helps users construct valid filters for LibSQL Vector.\n */\nexport const LIBSQL_PROMPT = `When querying LibSQL 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- $all: Match all values in array\n  Example: { \"tags\": { \"$all\": [\"premium\", \"sale\"] } }\n- $elemMatch: Match array elements that meet all specified conditions\n  Example: { \"items\": { \"$elemMatch\": { \"price\": { \"$gt\": 100 } } } }\n- $contains: Check if array contains value\n  Example: { \"tags\": { \"$contains\": \"premium\" } }\n\nLogical Operators:\n- $and: Logical AND (implicit when using multiple conditions)\n  Example: { \"$and\": [{ \"price\": { \"$gt\": 100 } }, { \"category\": \"electronics\" }] }\n- $or: Logical OR\n  Example: { \"$or\": [{ \"price\": { \"$lt\": 50 } }, { \"category\": \"books\" }] }\n- $not: Logical NOT\n  Example: { \"$not\": { \"category\": \"electronics\" } }\n- $nor: Logical NOR\n  Example: { \"$nor\": [{ \"price\": { \"$lt\": 50 } }, { \"category\": \"books\" }] }\n\nElement Operators:\n- $exists: Check if field exists\n  Example: { \"rating\": { \"$exists\": true } }\n\nSpecial Operators:\n- $size: Array length check\n  Example: { \"tags\": { \"$size\": 2 } }\n\nRestrictions:\n- Regex patterns are not supported\n- Direct RegExp patterns will throw an error\n- Nested fields are supported using dot notation\n- Multiple conditions on the same field are supported with both implicit and explicit $and\n- Array operations work on array fields only\n- Basic operators handle array values as JSON strings\n- Empty arrays in conditions are handled gracefully\n- Only logical operators ($and, $or, $not, $nor) can be used at the top level\n- All other operators must be used within a field condition\n  Valid: { \"field\": { \"$gt\": 100 } }\n  Valid: { \"$and\": [...] }\n  Invalid: { \"$gt\": 100 }\n  Invalid: { \"$contains\": \"value\" }\n- Logical operators must contain field conditions, not direct operators\n  Valid: { \"$and\": [{ \"field\": { \"$gt\": 100 } }] }\n  Invalid: { \"$and\": [{ \"$gt\": 100 }] }\n- $not operator:\n  - Must be an object\n  - Cannot be empty\n  - Can be used at field level or top level\n  - Valid: { \"$not\": { \"field\": \"value\" } }\n  - Valid: { \"field\": { \"$not\": { \"$eq\": \"value\" } } }\n- Other logical operators ($and, $or, $nor):\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- $elemMatch requires an object with conditions\n  Valid: { \"array\": { \"$elemMatch\": { \"field\": \"value\" } } }\n  Invalid: { \"array\": { \"$elemMatch\": \"value\" } }\n\nExample Complex Query:\n{\n  \"$and\": [\n    { \"category\": { \"$in\": [\"electronics\", \"computers\"] } },\n    { \"price\": { \"$gte\": 100, \"$lte\": 1000 } },\n    { \"tags\": { \"$all\": [\"premium\", \"sale\"] } },\n    { \"items\": { \"$elemMatch\": { \"price\": { \"$gt\": 50 }, \"inStock\": true } } },\n    { \"$or\": [\n      { \"stock\": { \"$gt\": 0 } },\n      { \"preorder\": true }\n    ]}\n  ]\n}`;\n"]}